<?php
/**
 * @Author: king
 * @Date:   2019-02-17 19:50:25
 * @Last Modified by:   king
 * @Last Modified time: 2019-06-06 18:18:08
 */

namespace App\Tools\Astrolog;

use App\Tools\Time;
use App\Exceptions\ApiException;

/**
 * 星盘数据类
 * Class Astrolog
 * @package App\Tools\Time
 */
class Astrolog
{
    public static $_instance;
    /**
     * @var array
     * planets_display 默认显示的行星
     * planets_orb 默认的行星容许度
     * asps_display 默认显示的相位
     * asps_orb 默认的相位容许度
     * h_sys 默认分宫制 p 普莱西度
     * setting 星盘的相关配置（当前方案的所有配置）
     * recode1 档案资料1
     *      同数据库存储的档案信息
     * recode2 档案资料2
     *      同数据库存储的档案信息
     * advance 推进时间 + 经纬度（天象盘时）
     *      year
     *      month
     *      day
     *      hour
     *      minute
     *      timezone
     *      is_summer
     *      longitude
     *      latitude
     * day_chart 是否为日间盘
     * use_default_setting 是否使用默认配置 【此时，setting 不能为空】
     * get_datas 需要获取的星盘数据【由chart组成的数组】
     * returnTime [日返|月返] 返照时间
     */
    public $options = [
        'planets_display' => '',
        'planets_orb' => [],
        'asps_display' => [],
        'asps_orb' => [],
        'h_sys' => 'p',
        'firdaria' => 'default',
        'setting' => [],
        'day_chart' => false,
    ];

    /**
     * exec_prefix exec 通用前缀字符
     * @var string
     */
    private $exec_prefix = '/data/seeastro/astrolog/astrolog_linux -edir/data/seeastro/astrolog/';

    /**
     * 错误信息
     * @var string
     */
    protected $error = '';

    /**
     * 用户档案1
     * @var array
     */
    protected $recode1 = [];

    /**
     * 用户档案2
     * @var array
     */
    protected $recode2 = [];

    /**
     * 星盘推进信息
     * @var array
     */
    protected $advance = [];

    /**
     * 需要获取的星盘数据
     * @var array
     */
    protected $getDatas = [];

    /**
     * 是否为画盘数据
     * @var bool
     */
    protected $isAstrolabe = false;

    /**
     * 是否使用默认配置
     * @var bool
     */
    protected $useDefaultSetting = false;

    /**
     * chart 与获取对应星盘数据方法关系
     * @var array
     */
    protected static $funcRelations = [
        'now'                       => 'getNowData',// 天象盘
        'natal'                     => 'getNatalData',// 本命盘
        'transits'                  => 'getTransitsData',// 行运盘
        'thirdprogressed'           => 'getThirdprogressedData',// 三限盘
        'thirdprogressedvsnatal'    => 'getThirdprogressedVsNatalData',// 三限双盘
        'progressions'              => 'getThirdprogressedData',// 次限盘
        'progressionsvsnatal'       => 'getThirdprogressedVsNatalData',// 次限双盘
        'solar'                     => 'getSolarData',// 太阳弧盘
        'firdaria'                  => 'getFirdariaData',// 法达盘
        'profection'                => 'getProfectionData',// 小限盘
        'synastry'                  => 'getSynastryData',// 比较盘
        'composite'                 => 'getCompositeData',// 组合中点盘
        'composite_thirdprogressed' => 'getCompositeThirdprogressedData',// 组合三限盘
        'composite_progressions'    => 'getCompositeThirdprogressedData',// 组合次限盘
        'davison'                   => 'getDavisonData',// 时空中点盘
        'solar_return'              => 'getSolarReturnData',// 太阳返照盘
        'solar_returnvsnatal'       => 'getSolarReturnVsNatalData',// 太阳返照双盘
        'lunar_return'              => 'getLunarReturnData',// 月亮返照盘
        'lunar_returnvsnatal'       => 'getLunarReturnVsNatalData',// 月亮返照双盘
        'marks'                     => 'getMarksData',// 马克思盘
        'divination'                => 'getDivinationData',// 卜卦盘
        'synastry_thirdprogressed'  => 'getSynastryThirdprogressedData',// 比较三限盘
        'synastry_progressions'     => 'getSynastryThirdprogressedData',// 比较次限盘
        'davison_thirdprogressed'   => 'getDavisonThirdprogressedData',// 时空三限盘
        'davison_progressions'      => 'getDavisonThirdprogressedData',// 时空次限盘
    ];

    protected $nowData = [];
    protected $natalData = [];
    protected $transitsData = [];
    protected $thirdprogressedData = [];
    protected $thirdprogressedvsnatalData = [];
    protected $progressionsData = [];
    protected $progressionsvsnatalData = [];
    protected $solarData = [];
    protected $firdariaData = [];
    protected $profectionData = [];
    protected $synastryData = [];
    protected $compositeData = [];
    protected $composite_thirdprogressedData = [];
    protected $composite_progressionsData = [];
    protected $davisonData = [];
    protected $solar_returnData = [];
    protected $solar_returnvsnatalData = [];
    protected $lunar_returnData = [];
    protected $lunar_returnvsnatalData = [];
    protected $marksData = [];
    protected $synastry_thirdprogressedData = [];
    protected $synastry_progressionsData = [];
    protected $davison_thirdprogressedData = [];
    protected $davison_progressionsData = [];

    /**
     * Astrolog constructor.
     */
    public function __construct()
    {
    }

    /**
     * 获取静态实例对象
     * @return Astrolog
     */
    public static function getInstance()
    {
        if (!(self::$_instance instanceof self))
        {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    /**
     * 设置用户档案1信息
     * @param array $param
     * @return $this
     */
    public function setRecode1($param = [])
    {
        $this->recode1 = $param;
        return $this;
    }

    /**
     * 设置用户档案2信息
     * @param array $param
     * @return $this
     */
    public function setRecode2($param = [])
    {
        $this->recode2 = $param;
        return $this;
    }

    /**
     * 设置星盘推进信息
     * @param array $param
     * @return $this
     */
    public function setAdvance($param = [])
    {
        $this->advance = $param;
        return $this;
    }

    /**
     * 设置是否获取画盘数据
     * @param bool $param
     * @return $this
     */
    public function setIsAstrolabe($param = false)
    {
        $this->isAstrolabe = $param;
        return $this;
    }

    /**
     * 设置获取星历数据时的前缀命令
     * @param string $param
     * @return $this
     */
    public function setExecPrefix($param = '')
    {
        $this->exec_prefix = $param;
        return $this;
    }

    /**
     * 设置要获取的星盘数据
     * @param array $param
     * @return $this
     */
    public function setGetDatas($param = [])
    {
        $this->getDatas = $param;
        return $this;
    }

    /**
     * 设置计算星盘数据时的星盘配置
     * @param array $param
     * @return $this
     */
    public function setUserSetting($param = [])
    {
        $this->options['setting'] = $param;
        return $this;
    }

    /**
     * 返回错误信息
     * @return string
     */
    public function getError()
    {
        return $this->error;
    }

    /**
     * 获取某个盘的数据
     * @param string $param
     * @return mixed
     */
    public function getDatas($param = '')
    {
        return $this->{$param . 'Data'};
    }

    /**
     * 获取占星数据
     */
    public function getAstroDatas()
    {
        if (!empty($this->getDatas))
        {
            foreach ($this->getDatas as $chart)
            {
                // 切换对应的星盘配置
                $this->switchConfiguration($chart);

                // 调用对应的获取星盘数据的方法
                if (strpos($chart, 'progressions') !== false)
                {
                    $this->{$chart . 'Data'} = $this->{self::$funcRelations[$chart]}(365.2422);
                } else
                {
                    $this->{$chart . 'Data'} = $this->{self::$funcRelations[$chart]}();
                }
            }
        }
        return $this;
    }

    /**
     * 检查档案时间格式
     * @param $year
     * @param $month
     * @param $day
     * @param $hour
     * @param $minute
     * @param $timezone
     * @return bool
     */
    public function checkRecodeData($year = null, $month = null, $day = null, $hour = null, $minute = null, $timezone = null)
    {
        // 年份限制 1900 - 2099
        if ($year === null || $year < 1000 || $year > 2999)
        {
            return false;
        }
        // 月份限制 1-12
        if ($month === null || $month < 0 || $month > 12)
        {
            return false;
        }
        $is_bissextile = $this->is_bissextile($year);// 是否为闰年
        // 日期限制 1-31
        if ($day === null || $day < 0 || $day > 31
            || ($is_bissextile && $month == 2 && $day > 29)
            || (!$is_bissextile && $month == 2 && $day > 28)
            || (in_array($month, [4, 6, 9, 11]) && $day > 30))
        {
            return false;
        }
        // 小时限制 0-23
        if ($hour === null || $hour < 0 || $hour > 23)
        {
            return false;
        }
        // 分钟限制 0-59
        if ($minute === null || $minute < 0 || $minute > 59)
        {
            return false;
        }
        if ($timezone < -12 || $timezone > 12)
        {
            return false;
        }
        return true;
    }

    /**
     * 判断是否为闰年
     * 闰年 true || 平年 false
     * @param null $year
     * @return bool
     */
    public function is_bissextile($year = null)
    {
        if ($year === null)
        {
            return false;
        }
        if ($year % 400 === 0 || ($year % 100 !== 0 && $year % 4 === 0))
        {
            return true;
        }
        return false;
    }

    /**
     * 时间信息处理
     * $utdatenow
     * $utnow
     * @param array $timeinfo1
     * @param array $timeinfo2
     * @return array|false|int
     */
    public function deal_time($timeinfo1 = [], $timeinfo2 = [])
    {

        $year1 = $timeinfo1['year'];
        $month1 = $timeinfo1['month'];
        $day1 = $timeinfo1['day'];
        $hour1 = $timeinfo1['hour'];
        $minute1 = $timeinfo1['minute'];
        $second1 = 0;
        $is_summer1 = $timeinfo1['is_summer'];
        $timezone1 = $timeinfo1['timezone'];

        $this->checkRecodeData($year1, $month1, $day1, $hour1, $minute1, $timezone1);

        // 夏令时
        if ($is_summer1) $hour1--;
        // 时区处理
        if ($timezone1 >= 0)
        {
            $whole1 = floor($timezone1);
            $fraction1 = $timezone1 - floor($timezone1);
        } else
        {
            $whole1 = ceil($timezone1);
            $fraction1 = $timezone1 - ceil($timezone1);
        }
        $hour1 = $hour1 - $whole1;
        $minute1 = $minute1 - ($fraction1 * 60);
        $date1 = mktime($hour1, $minute1, $second1, $month1, $day1, $year1);
        if (!empty($timeinfo2))
        {
            $year2 = $timeinfo2['year'];
            $month2 = $timeinfo2['month'];
            $day2 = $timeinfo2['day'];
            $hour2 = $timeinfo2['hour'];
            $minute2 = $timeinfo2['minute'];
            $second2 = 0;
            $is_summer2 = $timeinfo2['is_summer'];
            $timezone2 = $timeinfo2['timezone'];
            $this->checkRecodeData($year2, $month2, $day2, $hour2, $minute2, $timezone2);
            // 夏令时
            if ($is_summer2) $hour2--;
            // 时区处理
            if ($timezone2 >= 0)
            {
                $whole2 = floor($timezone2);
                $fraction2 = $timezone2 - floor($timezone2);
            } else
            {
                $whole2 = ceil($timezone2);
                $fraction2 = $timezone2 - ceil($timezone2);
            }
            $hour2 = $hour2 - $whole2;
            $minute2 = $minute2 - ($fraction2 * 60);

            $date2 = mktime($hour2, $minute2, $second2, $month2, $day2, $year2);
            return [$date1, $date2];
        } else
        {
            return $date1;
        }
    }

    /**
     * 检测运势推进时间是否早于出生时间
     * @param null $time1 出生时间
     * @param null $time2 推进时间
     * @return bool true时间正常|false时间异常
     */
    protected function checkTime($time1 = null, $time2 = null)
    {
        if ($time2 < $time1)
        {
            $this->error = '当前选择时间早于出生时间';
            return false;
        }
        return true;
    }

    /**
     * 获取星盘原始数据
     * @param array $data
     * @return array|bool
     */
    protected function getOriginalData($data = [])
    {
        if (empty($data) || count($data) < 20)
        {
            \Log::info('行星数据获取失败，请检查', array('astro_error'));
            $this->error = '';
            return false;
        }
        $planet = [];
        $speed = [];
        foreach ($data as $key => $line)
        {
            $row = explode(',', $line);
            $planet[$key] = @floatval($row[0]) * 1;
            $declination[$key] = isset($row[1]) ? floatval($row[1]) * 1 : 0;
            $speed[$key] = isset($row[2]) ? floatval($row[2]) * 1 : 0;
        };

        $juno = $planet[13];// 婚神星
        $vert = $planet[30];// 宿命点度数

        $asc = $planet[27];
        $mc = $planet[28];
        $des = $asc >= 180 ? $asc - 180 : $asc + 180;
        $ic = $mc >= 180 ? $mc - 180 : $mc + 180;

        // 判断是日间盘还是夜间盘
        if ($asc > $des)
            if ($planet[0] <= $asc && $planet[0] > $des)
                $day_chart = true;
            else
                $day_chart = false;
        else
            if ($planet[0] > $asc && $planet[0] <= $des)
                $day_chart = false;
            else
                $day_chart = true;

        // 计算福点位置
        if ($day_chart == true) $fort = $asc + $planet[1] - $planet[0];
        else $fort = $asc - $planet[1] + $planet[0];
        if ($fort >= 360) $fort -= 360;
        if ($fort < 0) $fort += 360;

        $hc = [];

        for ($i = 1; $i <= 14; $i++)
        {
            $hc[$i] = $planet[14 + $i];
            unset($planet[14 + $i]);
        }

        unset($hc[13]);
        unset($hc[14]);
        unset($planet[29]);
        unset($planet[30]);

        $planet[13] = $juno;// 婚神星
        $planet[14] = $fort;// 福点
        $planet[15] = $vert;// 宿命点
        $planet[16] = $planet[12] > 180 ? $planet[12] - 180 : $planet[12] + 180;// 增加南交点
        // 加四轴 放入行星组中
        $planet[17] = $asc;// 上升点
        $planet[18] = $ic;// 天底
        $planet[19] = $des;// 下降点
        $planet[20] = $mc;// 天顶

        $returnData = ['p1' => $planet, 'hc1' => $hc, 'speed' => $speed];

        $this->options['day_chart'] = $day_chart;

        return $returnData;
    }

    /**
     * 隐藏不显示的行星
     * @param $arr
     * @return void
     */
    protected function array_remove(&$arr)
    {
        $result = [];
        for ($i = 0; $i <= MC; $i++)
        {
            if ($this->options['planets_display'][$i] == 1)
            {
                $result['p1'][$i] = $arr['p1'][$i];
                $result['speed'][$i] = $arr['speed'][$i];
            }
        }
        $result['hc1'] = $arr['hc1'];

        $arr = $result;

        return;
    }

    /**
     * 获取行星所落宫位
     * @param $longitude
     * @param $house
     * @return int [type]            [description]
     */
    protected function getPlanetInHouse($longitude, $house)
    {

        $house[13] = $house[1];

        $in_house = 12;

        for ($j = 1; $j <= 12; $j++)
        {
            // 方便计算四轴
            $pl = $longitude + (1 / 36000);

            $h_now = @$house[$j];
            $h_next = @$house[$j + 1];

            if ($j < 12 && $h_now > $h_next)
            {
                if (($pl >= $h_now && $pl < 360) || ($pl < $h_next && $pl >= 0))
                {
                    return $j;
                }
            }
            if ($j == 12 && ($h_now > $house[1]))
            {
                if (($pl >= $h_now && $pl < 360) || ($pl < $house[1] && $pl >= 0))
                {
                    return $j;
                }
            }
            if (($pl >= $h_now) && ($pl < $h_next && ($j < 12)))
            {
                return $j;
            }
            if (($pl >= $h_now) && ($pl < $house[1]) && ($j == 12))
            {
                return $j;
            }
        }
        return $in_house;
    }

    /**
     * 行星落入星座度数
     * 如：18°2'26''
     * @param $deg
     * @return float [type] [description]
     */
    protected function inSignDegFloor($deg)
    {

        $sign_id = floor($deg / 30);

        $pos_in_sign = $deg - ($sign_id * 30);

        return floatval($pos_in_sign);
    }

    /**
     * 入星座度数
     * 如：18°2'26''  || 18°3′
     * @param $deg
     * @param bool $get_sec
     * @return string [type] [description]
     */
    protected function inSignDeg($deg, $get_sec = false)
    {
        $longitude = $deg;
        $sign_id = floor($longitude / 30);
        $pos_in_sign = $longitude - ($sign_id * 30);
        $deg = floor($pos_in_sign);
        $full_min = ($pos_in_sign - $deg) * 60;
        $min = floor($full_min);
        $sec = round(($full_min - $min) * 60);
        if ($deg < 10) $deg = '    ' . $deg;
        if ($min < 10) $min = '0' . $min;
        if ($sec < 10) $sec = '0' . $sec;
        if (!$get_sec)
        {
            // 四舍五入
            if ($sec >= 30) $min++;
            if ($min == 60)
            {
                $min = 0;
                $deg++;
            }
            return $deg . '°' . $min . "′";
        }
        return $deg . '°' . $min . "′" . $sec . '″';
    }

    /**
     * 获取
     * 行星
     * 宫头
     * 详细信息
     * @param  [type] $data [description]
     * @param array $house
     * @param int $year
     * @return array [type]       [description]
     */
    protected function getPlanetHouseDetail($data, $house = array(), $year = 0)
    {
        $planetHouseDetails = [];

        for ($i = 0; $i <= MC; $i++)
        {
            // 不显示的行星不进行处理
            if (!isset($data['p1'][$i])) continue;

            $longitude = $data['p1'][$i];
            $in_sign = ceil($longitude / 30);// 行星在星座
             if ($in_sign < 1) $in_sign = 1;// 整宫制上升0°时 BUG修复
            elseif ($in_sign > 12) $in_sign = 12;// 360/12 ceil后为13
            $in_sign_deg = $this->inSignDeg($longitude);// 行星在星座的度数
            $in_sign_deg_e = $longitude - ($in_sign - 1) * 30;// 行星在星座的度数
            $in_house = $this->getPlanetInHouse($longitude, $house);// 行星落宫
            $speed = @$data['speed'][$i] ? $data['speed'][$i] : 0;// 行星速度

            $planetHouseDetails['planets'][$i]['id'] = $i;
            $planetHouseDetails['planets'][$i]['speed'] = $speed;
            $planetHouseDetails['planets'][$i]['deg'] = $longitude * 1;
            $planetHouseDetails['planets'][$i]['in_sign_id'] = $in_sign;
//            echo json_encode(['id'=>$i,'msg'=>$longitude,'sign'=>$in_sign]);
            $planetHouseDetails['planets'][$i]['in_sign_deg'] = $in_sign_deg;
            $planetHouseDetails['planets'][$i]['in_sign_deg_e'] = $in_sign_deg_e;

            $planetHouseDetails['planets'][$i]['in_house_id'] = $in_house;
            $planetHouseDetails['planets'][$i]['ancient'] = $this->planet_in_ancient($i, $in_sign, $this->inSignDegFloor($longitude));
            $sun_in_out = $this->oriental_or_occidental_sun($i, $data['p1'][0], $longitude);// 东出西入
            $planetHouseDetails['planets'][$i]['ancient']['sun_in_out'] = $sun_in_out;
            $planetHouseDetails['planets'][$i]['ancient']['hagy'] = $this->planet_hagy($i, $in_sign, $in_house, $sun_in_out);
            $planetHouseDetails['planets'][$i]['ancient']['sun_dist'] = $this->planet_sun_dist($i, $data['p1'][0], $longitude);
            $planetHouseDetails['planets'][$i]['ancient']['like_house'] = $this->planet_in_like_house($i, $in_house);
            $planetHouseDetails['planets'][$i]['ancient']['burn_way'] = $this->planet_in_burn_way($i, $in_sign, $in_sign_deg);
            $planetHouseDetails['planets'][$i]['ancient']['antipode'] = $this->planet_antipode($i, $longitude, $data['p1']);
            $planetHouseDetails['planets'][$i]['ancient']['star'] = [];

            if ($year > 0)
            {
                if (!in_array($i, [0, 1, 2, 3, 4, 5, 6, ASC, IC, DES, MC])) continue;
                $diff = ($year * 1 - 2000) * 0.83 / 60;
                // 计算恒星 每一百年移动83′ 每年0.83分
                foreach (config('astrolog.star') as $s)
                {
                    $star = $s[0] + $diff;
                    if ($star >= 360) $star -= 360;
                    $light = $s[4];// 亮度

                    $da = abs($longitude - $star);
                    // 亮度小于1.4，容许度2；亮度1.4-2.1，容许度1.5    20180211 edit by Seunk
                    if (
                        ($da <= 2 && $light < 1.4)
                        || ($da >= 358 && $da <= 360 && $light < 1.4)
                        || ($da <= 2 && $light >= 1.4 && $light < 2.1)
                        || ($da >= 358 && $da <= 360 && $light >= 1.4 && $light < 2.1)
                        || ($da <= 1 && $light >= 2.1)
                        || ($da >= 359 && $da <= 360 && $light >= 2.1)
                    )
                    {
                        $s_in_sign = ceil($star / 30);// 行星在星座
                        $s_in_sign_deg = $this->inSignDeg($star);// 行星在星座的度数  不显示秒
                        $s_s = [
                            'deg' => $star,
                            'name' => $s[1],
                            'belong_sign' => $s[2],
                            'planet_attr' => $s[3],
                            'influences' => $s[4],
                            'description' => $s[5],
                            'auspicious' => $s[6],// 吉凶状态  凶 平 吉 大吉
                            'in_sign_deg' => $s_in_sign_deg,
                            'in_sign' => $s_in_sign,
                            'con_planet_id' => $i,
                        ];
                        if ($s[1] == '壁宿二' && $i == 0)
                        {
                            $s_s['auspicious'] = '凶';
                        } elseif ($s[1] == '天狼星' && $i == MC)
                        {
                            $s_s['auspicious'] = '大吉';
                        } elseif ($s[1] == '水委一' && $i == 5)
                        {
                            $s_s['auspicious'] = '大吉';
                        } elseif ($s[1] == '北落师门' && ($i == 2 || $i == 3))
                        {
                            $s_s['auspicious'] = '吉';
                        } elseif ($s[1] == '参宿七' && ($i == 0 || $i == 1 || $i == ASC || $i == MC))
                        {
                            $s_s['auspicious'] = '大吉';
                        } elseif ($s[1] == '参宿四' && $i == 4)
                        {
                            $s_s['auspicious'] = '凶';
                        } elseif ($s[1] == '太微左垣一' && ($i == 4 || $i == 6))
                        {
                            $s_s['auspicious'] = '平';
                        } elseif ($s[1] == '贯索四' && ($i == 4 || $i == 8))
                        {
                            $s_s['auspicious'] = '平';
                        } elseif ($s[1] == '马腹一')
                        {
                            if (($i == ASC || $i == 2) && ($i == 4 || $i == 6 || $i == 8))
                            {
                                $s_s['auspicious'] = '平';
                            } elseif ($i == ASC || $i == 2)
                            {
                                $s_s['auspicious'] = '吉';
                            } elseif ($i == 4 || $i == 6 || $i == 8)
                            {
                                $s_s['auspicious'] = '凶';
                            }
                        }

                        $planetHouseDetails['planets'][$i]['ancient']['star'][] = $s_s;
                        $planetHouseDetails['star'][] = $s_s;
                    }
                }
            } else
            {
                $planetHouseDetails['planets'][$i]['ancient']['star'] = null;
                $planetHouseDetails['star'] = null;
            }

        }

        //循环12宫
        for ($i = 1; $i <= 12; $i++)
        {
            $house_deg = @$house[$i] * 1;
            if ($house_deg > 360) $house_deg -= 360;

            $in_sign = (int)ceil($house_deg / 29.999999999999);
            if ($in_sign < 1) $in_sign = 1;// 整宫制上升0°时 BUG修复
            elseif ($in_sign > 12) $in_sign = 12;// 360/12 ceil后为13
            $in_sign_deg = $this->inSignDeg($house_deg);

            $planetHouseDetails['houses'][$i]['deg'] = $house_deg;
            $planetHouseDetails['houses'][$i]['in_sign_id'] = $in_sign;
            $planetHouseDetails['houses'][$i]['in_sign_deg'] = $in_sign_deg;
            // 现占 // 宫主星信息
            $protect_id = config('astrolog.protect_id')[$in_sign - 1];// 宫主星id
            $planetHouseDetails['houses'][$i]['protect_id'] = $protect_id;

            $planetHouseDetails['houses'][$i]['protect_insign_id'] = $planetHouseDetails['planets'][$protect_id]['in_sign_id'];
            $planetHouseDetails['houses'][$i]['protect_insign_deg'] = $planetHouseDetails['planets'][$protect_id]['in_sign_deg'];
            // 现占 // 宫主飞星信息
            $planetHouseDetails['houses'][$i]['protect_inhouse_id'] = $planetHouseDetails['planets'][$protect_id]['in_house_id'];

            // 古占 // 宫主星信息
            $protect_ancient_id = config('astrolog.protect_ancient_id')[$in_sign - 1];// 宫主星id
            $planetHouseDetails['houses'][$i]['protect_ancient_id'] = $protect_ancient_id;
            $planetHouseDetails['houses'][$i]['protect_ancient_insign_id'] = $planetHouseDetails['planets'][$protect_ancient_id]['in_sign_id'];
            $planetHouseDetails['houses'][$i]['protect_ancient_insign_deg'] = $planetHouseDetails['planets'][$protect_ancient_id]['in_sign_deg'];
            // 古占 // 宫主飞星信息
            $planetHouseDetails['houses'][$i]['protect_ancient_inhouse_id'] = $planetHouseDetails['planets'][$protect_ancient_id]['in_house_id'];
            $planetHouseDetails['houses'][$i]['in_house_area_planet_info'] = [];// 落入当前宫位的行星信息
            $num = 0;
            foreach ($planetHouseDetails['planets'] as $k => $pls)
            {
                if ($this->options['planets_display'][$k] != 1) continue;
//                if ($k != 17 && $k != IC && $k != DES && $k != 20 && $pls['in_house_id'] == $i)
                if ($k < 10 && $pls['in_house_id'] == $i)
                {
                    $planetHouseDetails['houses'][$i]['in_house_area_planet_info'][] = [
                        'id' => $k,
                        'deg' => $planetHouseDetails['planets'][$k]['deg'],// 行星度数
                    ];
                    $num++;
                }
            }
            $planetHouseDetails['houses'][$i]['have_planet_num'] = $num;// 计算当前宫位有几个行星

            $planetHouseDetails['houses'][$i]['house_almuten'] = $this->house_almuten($in_sign, $this->inSignDegFloor($house_deg));//宫神星
        }
        $planetHouseDetails['arabics'] = $this->getTheArabics($planetHouseDetails['planets'], $planetHouseDetails['houses'], $this->options['day_chart']);

        return $planetHouseDetails;
    }

    /**
     * 获取行星间相位信息
     * @param array $data1
     * @param array $data2
     * @param bool $pkself
     * @param int $vs
     * @return array
     */
    protected function planetPkPlanet($data1 = array(), $data2 = array(), $pkself = false, $vs = 0)
    {
        $planetPkPlanet = [];
        $planetPkPlanet['phase'] = [];
        $planet1 = $data1['p1'];
        $planet2 = $data2['p1'];
        $speed1 = $data1['speed'];
        $speed2 = $data2['speed'];
        // 相位计算
        for ($i = 0; $i <= 20; $i++)
        {
            if (!isset($planet1[$i])) continue;
            // 行星1 度数
            $longitude1 = $planet1[$i];
            $p_orb1 = $this->options['planets_orb'][$i] ?? 0;
            $planetPkPlanetPhase = [];
            for ($j = 0; $j <= 20; $j++)
            {
                if (!isset($planet2[$j])) continue;
                // 行星2 度数
                $longitude2 = $planet2[$j];
                $q = -1;
                // 避免重复
                if ($pkself == true && ($i == $j || ($i >= 17 && $j >= 17))) continue;
                $da = abs($longitude1 - $longitude2);
                if ($da > 180) $da = 360 - $da;

                $p_orb2 = $this->options['planets_orb'][$j] ?? 0;
                $p_orb = $p_orb1 + $p_orb2;
                $orb = null;
                // 判断相位
                foreach ($this->options['asps_display'] as $k => $asps)
                {
                    $asp_deg = $asps;

                    $asp_deg_orb = $this->options['asps_orb'][$asp_deg];

                    if (($da <= ($asp_deg + $asp_deg_orb + $p_orb)) && ($da >= ($asp_deg - $asp_deg_orb - $p_orb)))
                    {
                        $q = $asp_deg;
                        $orb = $asp_deg_orb + $p_orb;
                    }

                }
                if ($q >= 0)
                {
                    $phase_orb = floatval(number_format(abs($da - $q), 6));
                    // 计算出入相位----------------------------------------------
                    if ($i >= ASC || $j >= ASC)
                    {
                        $in_or_out = -1;
                    } else
                    {
                        $in_or_out_status = $this->phase_in_or_out($q, $longitude1, $longitude2, $speed1[$i], $speed2[$j], $phase_orb, $vs);
                        if ($in_or_out_status) $in_or_out = 1;// 入相
                        else $in_or_out = 0;// 出相
                    }
                    $planetPkPlanetPhase[$i . '-' . $j]['phase_e'] = $q;
                    $planetPkPlanetPhase[$i . '-' . $j]['phase_or_orb'] = $orb;
                    $planetPkPlanetPhase[$i . '-' . $j]['phase_orb'] = $phase_orb;
                    $planetPkPlanetPhase[$i . '-' . $j]['phase_change'] = $in_or_out;
                    $planetPkPlanetPhase[$i . '-' . $j]['id'] = $j;
                    // 判断相位方向  用于区分如同向90° 和  两个方向的90°
                    if ($q == 0 || $q == 180)
                    {
                        $planetPkPlanetPhase[$i . '-' . $j]['phase_type'] = 0;// 相位方向
                    } else
                    {
                        if ($longitude1 < $longitude2 || ($longitude2 - $longitude1) > 180)
                        {
                            $planetPkPlanetPhase[$i . '-' . $j]['phase_type'] = 1;
                        } else
                        {
                            $planetPkPlanetPhase[$i . '-' . $j]['phase_type'] = -1;
                        }
                    }
                    $planetPkPlanet['phase'][] = [
                        'id1' => $i,
                        'id2' => $j,
                        'phase_deg' => $q,
                        'orb' => number_format(abs($da - $q), 6) * 1,
                        'or_orb' => $orb,
                    ];
                }
            }
            $planetPkPlanet['planets'][$i]['phase'] = $planetPkPlanetPhase;
        }
        return $planetPkPlanet;
    }

    /**
     *  获取太阳弧数据
     * @param  [type] $p_sun [太阳度数]
     * @param array $data
     * @return array [type]        [太阳弧行星数据]
     */
    protected function getTheLongitudeBySolarArc($p_sun, $data = [])
    {
        $p1 = $data['p1'];

        $solar_arc = Crunch($p_sun - $p1[0]);

        $longitude = [];

        foreach ($p1 as $i => $p)
        {
            $longitude[$i] = Crunch($p + $solar_arc);
        }

        $ret = ['p1' => $longitude, 'speed' => $data['speed']];

        return $ret;
    }

    /**
     * [组合盘中点计算]
     * @param array $data1 [description]
     * @param array $data2 [description]
     * @return array [type]        [description]
     */
    protected function getTheCompoisteCenter($data1 = array(), $data2 = array())
    {
//        $ret = [];

        $rx1 = "";

        for ($i = 0; $i <= 12; $i++)
        {
            $rx1 .= " ";
        }

        $longitude = $speed = $hc1x = $hc2x = $hc3x = $hc3 = [];

        foreach ($data1['p1'] as $i => $d)
        {
            $longitude[$i] = ($data1['p1'][$i] + $data2['p1'][$i]) / 2;
            $diff = abs($data1['p1'][$i] - $data2['p1'][$i]);

            if (
                $diff >= 180
                && abs($longitude[$i] - $data1['p1'][$i]) > 90
                && abs($longitude[$i] - $data2['p1'][$i]) > 90
            )
            {
                $longitude[$i] += 180;
            }

            $longitude[$i] = floatval(sprintf("%.3f", Crunch($longitude[$i])));

            $speed[$i] = ($data1['speed'][$i] + $data2['speed'][$i]) / 2;
        }

        for ($i = 10; $i <= 12; $i++)
        {
            $hc1x[$i - 9] = $data1['hc1'][$i];
            $hc2x[$i - 9] = $data2['hc1'][$i];
        }

        for ($i = 1; $i <= 9; $i++)
        {
            $hc1x[$i + 3] = $data1['hc1'][$i];
            $hc2x[$i + 3] = $data2['hc1'][$i];
        }

        for ($i = 1; $i <= 12; $i++)
        {
            $hc3x[$i] = ($hc1x[$i] + $hc2x[$i]) / 2;
            if (abs($hc3x[$i] - $hc1x[$i]) > 90 Or abs($hc3x[$i] - $hc2x[$i]) > 90)
            {
                $hc3x[$i] = $hc3x[$i] + 180;
            }

            if ($hc3x[$i] >= 360)
            {
                $hc3x[$i] = $hc3x[$i] - 360;
            }

            if ($i >= 2)
            {
                if (abs($hc3x[$i] - $hc3x[$i - 1]) > 90 And abs($hc3x[$i] - $hc3x[$i - 1]) < 270)
                {
                    $hc3x[$i] = Crunch($hc3x[$i] + 180);
                }
            }
        }

        for ($i = 1; $i <= 9; $i++)
        {
            $hc3[$i] = sprintf("%.3f", $hc3x[$i + 3]);
        }

        for ($i = 10; $i <= 12; $i++)
        {
            $hc3[$i] = sprintf("%.3f", $hc3x[$i - 9]);
        }

        $longitude[ASC] = $hc3[1];
        $longitude[IC] = $hc3[4];
        $longitude[DES] = $hc3[7];
        $longitude[MC] = $hc3[10];

        $ret = ['rx1' => $rx1, 'p1' => $longitude, 'hc1' => $hc3, 'speed' => $speed];

        return $ret;
    }

    /**
     * * 三限盘数据计算
     * @param array $before 上整月
     * @param array $after 下整月
     * @param int $changePro 变化比率
     * @return array
     */
    protected function getProgressionThirdprogressed($before = array(), $after = array(), $changePro = 0)
    {
        $temp = [];
        foreach ($before as $k => $v)
        {
            $t1 = explode(',', $before[$k]);
            $t2 = explode(',', $after[$k]);
            $p1 = $t1[0] * 1;
            $p2 = $t2[0] * 1;

            if (abs($p1 - $p2) > 180)
            {
                $p = $p1 + ($p2 + 360 - $p1) * $changePro;
            } else
            {
                $p = $p1 + ($p2 - $p1) * $changePro;
            }
            if ($p >= 360) $p = $p - 360;
            elseif ($p < 0) $p = $p + 360;
            // TODO d/s   计算真实平均值
            $r1 = isset($t1[2]) ? $t1[2] * 1 : 0;
//            $r2 = isset($t2[2]) ? $t2[2] * 1 : 0;
//            $r = $r1 + ($r2 - $r1) * $changePro;

            $temp[] = $p . ',' . $t1[1] . ',' . $r1;
        }

        return $temp;
    }

    /**
     * 计算行星  1入庙 或 2失势
     * @param null $p_id 行星ID
     * @param null $p_insign_id 行星落座id
     * @param float $p_insign_deg 行星落座度数
     * @return array
     */
    protected function planet_in_ancient($p_id = null, $p_insign_id = null, $p_insign_deg = 0.0)
    {
        // 非古典七星落座位置也有该位置庙旺弱陷界十度信息
        if ($p_id === null || $p_id < 0 || $p_insign_id === null) return null;
        $ret = [
            'plus' => 0,// 加分项，用来判断接纳互容
            'power' => 0,
            'walls' => -1, 'walls_cn' => '',// 庙
            'promote' => -1, 'promote_cn' => '',// 旺
            'trisection' => -1, 'trisection_cn' => '',// 三分
            'extent' => -1, 'extent_cn' => '',// 界
            'period' => -1, 'period_cn' => '',// 面
            'migration' => -1, 'migration_cn' => '',// 游走
            'or_walls_planet_id' => -1, 'or_promote_planet_id' => -1,
            'or_extent_planet_id' => -1, 'or_period_planet_id' => -1,
            'or_trisection_planet_id' => [],
        ];

        $fall = ($p_insign_id <= 6) ? ($p_insign_id + 6) : ($p_insign_id - 6);

        $config_ancient = config('astrolog.ancient')[$p_insign_id];
        $config_ancient_fall = config('astrolog.ancient')[$fall];

        // 入庙
        if ($p_id < 7 && $config_ancient[0] == $p_id)
        {
            $ret['plus'] += 5;
            $ret['power'] += 5;
            $ret['walls'] = 1;
            $ret['walls_cn'] = '入庙';
        } elseif ($p_id < 7 && $config_ancient_fall[0] == $p_id)
        {
            $ret['power'] -= 5;
            $ret['walls'] = 2;
            $ret['walls_cn'] = '失势';
        }

        $ret['or_walls_planet_id'] = $config_ancient[0];
        $ret['or_walls_fall_planet_id'] = $config_ancient_fall[0];
        // 天王星  入庙 失势
        if ($p_id == 7)
        {
            if ($p_insign_id == 11)
            {
                $ret['plus'] += 5;
                $ret['power'] += 5;
                $ret['walls'] = 1;
                $ret['walls_cn'] = '入庙';
            } elseif ($p_insign_id == 5)
            {
                $ret['power'] -= 5;
                $ret['walls'] = 2;
                $ret['walls_cn'] = '失势';
            }
        }
        // 海王星  入庙 失势
        if ($p_id == 8)
        {
            if ($p_insign_id == 12)
            {
                $ret['plus'] += 5;
                $ret['power'] += 5;
                $ret['walls'] = 1;
                $ret['walls_cn'] = '入庙';
            } elseif ($p_insign_id == 6)
            {
                $ret['power'] -= 5;
                $ret['walls'] = 2;
                $ret['walls_cn'] = '失势';
            }
        }
        // 冥王星  入庙 失势
        if ($p_id == 9)
        {
            if ($p_insign_id == 8)
            {
                $ret['plus'] += 5;
                $ret['power'] += 5;
                $ret['walls'] = 1;
                $ret['walls_cn'] = '入庙';
            } elseif ($p_insign_id == 2)
            {
                $ret['power'] -= 5;
                $ret['walls'] = 2;
                $ret['walls_cn'] = '失势';
            }
        }
        // 擢升
        if ($config_ancient[1] !== '' && $config_ancient[1] == $p_id)
        {
            $ret['plus'] += 4;
            $ret['power'] += 4;
            $ret['promote'] = 1;
            $ret['promote_cn'] = '擢升';
        } elseif ($config_ancient_fall[1] !== '' && $config_ancient_fall[1] == $p_id)
        {
            $ret['power'] -= 4;
            $ret['promote'] = 2;
            $ret['promote_cn'] = '落陷';
        }
        // 当擢升没有时  保持原始值-1【int】
        $ret['or_promote_planet_id'] = $config_ancient[1] !== '' ? $config_ancient[1] : -1;
        $ret['or_promote_fall_planet_id'] = $config_ancient_fall[1] !== '' ? $config_ancient_fall[1] : -1;
        // 三分
        if (in_array($p_id, $config_ancient[2]))
        {
            $ret['plus'] += 3;
            $ret['power'] += 3;
            $ret['trisection'] = 1;
            $ret['trisection_cn'] = '三分';
        }
        $ret['or_trisection_planet_id'] = $config_ancient[2];
        // 界主 界主为1 +2
        // 使用埃及界
        $extent = $config_ancient[3]['default'];

        for ($i = 0; $i < 5; $i++)
        {
            if ($p_insign_deg > $extent[1][$i] && $p_insign_deg < $extent[1][$i + 1])
            {
                if ($extent[0][$i] == $p_id)
                {
                    $ret['plus'] += 2;
                    $ret['power'] += 2;
                    $ret['extent'] = 1;
                    $ret['extent_cn'] = '界主';
                }
                $ret['or_extent_planet_id'] = $extent[0][$i];
            }
        }
        // 旬主或十度
        for ($i = 0; $i < 3; $i++)
        {
            $min = $i * 10;
            $max = $min + 10;
            if ($p_insign_deg > $min && $p_insign_deg < $max)
            {
                if ($config_ancient[4][$i] == $p_id)
                {
                    $ret['plus'] += 1;
                    $ret['power'] += 1;
                    $ret['period'] = 1;
                    $ret['period_cn'] = '旬主';
                }
                $ret['or_period_planet_id'] = $config_ancient[4][$i];
            }
        }

        if ($ret['walls'] == -1 && $ret['promote'] == -1 && $ret['trisection'] == -1 && $ret['extent'] == -1 && $ret['period'] == -1 && $ret['power'] == 0 && $p_id < 7)
        {
            $ret['power'] = -5;
            $ret['migration'] = 1;
            $ret['migration_cn'] = '游走';
        }
        if ($p_id > 6 && $p_id < 9 && $ret['walls'] == -1)
        {
            $ret['power'] = -5;
            $ret['migration'] = 1;
            $ret['migration_cn'] = '游走';
        }
        // 所有星座的29°
        if ($p_insign_deg >= 29) $ret['diversity'] = '岐度';
        else $ret['diversity'] = '';

        // 基本星座（白羊、巨蟹、天秤、摩羯）：0°，13°，26°
        // 固定星座（金牛、狮子、天蝎、水瓶）：9°，21°
        // 变动星座（双子、处女、射手、双鱼）：4°，17°
        if ((in_array($p_insign_id, [1, 4, 7, 10]) && in_array(floor($p_insign_deg), [0, 13, 26]))
            || (in_array($p_insign_id, [2, 5, 8, 11]) && in_array(floor($p_insign_deg), [9, 21]))
            || (in_array($p_insign_id, [3, 6, 9, 12]) && in_array(floor($p_insign_deg), [4, 17])))
            $ret['vital'] = '紧要度数';
        else $ret['vital'] = '';

        // 金牛座的29度、狮子座 6度、射手座 8度
        if (($p_insign_id == 2 && floor($p_insign_deg) == 29)
            || ($p_insign_id == 5 && floor($p_insign_deg) == 6)
            || ($p_insign_id == 9 && floor($p_insign_deg) == 8)
        )
            $ret['defect'] = '缺点度数';
        else $ret['defect'] = '';

        return $ret;
    }

    /**
     * 计算12个宫头  宫神星
     * @param int $insignid
     * @param int $insigndeg
     * @return array
     */
    protected function house_almuten($insignid = 0, $insigndeg = 0)
    {
        $score = [0, 0, 0, 0, 0, 0, 0];// 初始分数为0
        $data = config('astrolog.ancient')[$insignid];
        $score[$data[0]] += 5;// 本垣
        if ($data[1] != '') $score[$data[1]] += 4;// 擢升
        $score[$data[2][0]] += 3;// 三分 此处取第一三分主星
        // TODO 托勒密界 || 埃及界  配置判断
        // 界主 界主为1 +2
//        if (session('xzns.extent') == 'ptolemy_world')
//            $extent = $data[3]['ptolemy_world'];
//        else
        $extent = $data[3]['default'];

        for ($i = 0; $i < 5; $i++)
        {
            if ($insigndeg > $extent[1][$i] && $insigndeg < $extent[1][$i + 1])
                $score[$extent[0][$i]] += 2;// 界
            if ($i < 3)
            {
                $min = $i * 10;
                $max = $min + 10;
                if ($insigndeg > $min && $insigndeg < $max)
                    $score[$data[4][$i]] += 1;// 面
            }
        }
        $pid = array_search(max($score), $score);
        // 分值最高星为宫神星
        return $pid;
    }

    /**
     * 计算得时失时
     * @param null $pid
     * @param int $insignid
     * @param int $inhouseid
     * @param int $sun_in_out
     * @return int
     */
    protected function planet_hagy($pid = null, $insignid = 0, $inhouseid = 0, $sun_in_out = 0)
    {
        if ($pid > 6) return -1;// 只计算日月水金火木土0123456
        $day_planet = [0, 5, 6];// 昼行星
        $night_planet = [1, 3, 4];// 夜行星
        if ($pid == 2)
        {
            // 水星东出为昼行星  西入为夜行星
            if ($sun_in_out == 0) $day_planet[] = 2;
            elseif ($sun_in_out == 1) $night_planet[] = 2;
        }
        // 日生盘
        if ($this->options['day_chart'] == true)
        {
            // 得时
            if (in_array($pid, $day_planet) && $insignid % 2 == 1 && $inhouseid > 6) return 0;// 得时
            // 失时
            if (in_array($pid, $night_planet) && $insignid % 2 == 1 && $inhouseid > 6) return 1;// 失时
        } // 夜生盘
        else
        {
            // 得时
            if (in_array($pid, $night_planet) && $insignid % 2 == 0 && $inhouseid > 6) return 0;
            // 失时
            if (in_array($pid, $day_planet) && $insignid % 2 == 0 && $inhouseid > 6) return 1;
        }
        return -1;
    }

    /**
     * 计算行星的东出西入
     * @param null $pid
     * @param int $sunDeg
     * @param int $pDeg
     * @return string
     */
    protected function oriental_or_occidental_sun($pid = null, $sunDeg = 0, $pDeg = 0)
    {
        if ($pid > 6 || !$pid) return -1;
        if ($sunDeg > 180)
        {
            $min = $sunDeg - 180;
            $max = $sunDeg;
            if ($pDeg > $min && $pDeg < $max) return 0;// 东出
            if ($pDeg < $min || $pDeg > $max) return 1;// 西入
        } else
        {
            $min = $sunDeg;
            $max = $sunDeg + 180;
            if ($pDeg > $min && $pDeg < $max) return 1;// 西入
            if ($pDeg < $min || $pDeg > $max) return 0;// 东出

        }
        return false;
    }

    /**
     * 计算行星是否在日光下  灼伤 日心
     * @param null $pid
     * @param int $sunDeg
     * @param int $pDeg
     * @return string
     */
    protected function planet_sun_dist($pid = null, $sunDeg = 0, $pDeg = 0)
    {
        if ($pid > 6 || !$pid) return -1;
        if (abs($sunDeg - $pDeg) > 270)
        {
            if ($sunDeg > $pDeg)
                $dist = $pDeg + 360 - $sunDeg;
            else
                $dist = $sunDeg + 360 - $pDeg;
        } else
        {
            $dist = abs($sunDeg - $pDeg);
        }
        if ($dist > 17.5) return 0;// 无
        elseif ($dist > 8.5) return 1;// 在日光下
        elseif ($dist > 17 / 60) return 2;// 灼伤
        else return 3;// 日心 日核
    }

    /**
     * 判断行星 喜乐宫
     * @param null $pid
     * @param int $inhouseid
     * @return array
     */
    protected function planet_in_like_house($pid = null, $inhouseid = 0)
    {
        if ($pid === null || !$inhouseid || $pid > 6) return [-1, -1];
        if ($pid == 0)
            if ($inhouseid == 9) return [1, 9];
            else return [0, 9];
        elseif ($pid == 1)
            if ($inhouseid == 3) return [1, 3];
            else return [0, 3];
        elseif ($pid == 2)
            if ($inhouseid == 1) return [1, 1];
            else return [0, 1];
        elseif ($pid == 3)
            if ($inhouseid == 5) return [1, 5];
            else return [0, 5];
        elseif ($pid == 4)
            if ($inhouseid == 6) return [1, 6];
            else return [0, 6];
        elseif ($pid == 5)
            if ($inhouseid == 11) return [1, 11];
            else return [0, 11];
        else
            if ($inhouseid == 12) return [1, 12];
            else return [0, 12];
    }

    /**
     * 判断行星是否位于燃烧之路
     * @param null $pid 行星id
     * @param int $insignid 行星落座id
     * @param int $insigndeg 行星落在当前星座多少度
     * @return bool|string
     */
    protected function planet_in_burn_way($pid = null, $insignid = 0, $insigndeg = 0)
    {
        if ($pid > 6 || $pid === null || !$insignid) return -1;
        if (($insignid == 7 && $insigndeg >= 15) || ($insignid == 8 && $insigndeg <= 15)) return 1;// 燃烧之路
        else return 0;
    }

    /**
     * 计算古典七星-行星映点antipode 与 反映点reflect
     * @param null $pid 行星
     * @param int $pDeg
     * @param array $p
     * @return array
     */
    protected function planet_antipode($pid = null, $pDeg = 0, $p = [])
    {
        $orb = 2;
        if ($pid > 6 || $pid === null || empty($p)) return null;
        // 离冬至点即摩羯座0°近
        if (abs($pDeg - 90) > abs($pDeg - 270)) $axisDeg = 540;
        // 离夏至点即巨蟹座0°近
        else $axisDeg = 180;

        $antipode_deg = $axisDeg - $pDeg;
        $reflect_deg = $antipode_deg > 180 ? $antipode_deg - 180 : $antipode_deg + 180;

        $ret['antipode_deg'] = $antipode_deg;
        $ret['reflect_deg'] = $reflect_deg;
        $ret['antipode_planet'] = [];
        $ret['reflect_planet'] = [];

        foreach ($p as $i => $d)
        {
            if ($i > MC) continue;
            if (abs($antipode_deg - $d) <= $orb) $ret['antipode_planet'][] = $i;
            if (abs($reflect_deg - $d) <= $orb) $ret['reflect_planet'][] = $i;
        }

        return $ret;
    }

    /**
     * 计算互容接纳
     * @param array $planets
     * @return array
     */
    protected function recept_or_mutual_recept($planets = [])
    {
        $ret = [];
        $miscible = [];// 互溶
        $accept = [];// 接纳
        // 古典七星
        for ($i = 0; $i <= 5; $i++)
        {
            for ($l = 0; $l <= 6; $l++)
            {
                $i_ancient = $this->planet_in_ancient($i, $planets[$l]['in_sign_id'], $planets[$l]['in_sign_deg_e']);
                $l_ancient = $this->planet_in_ancient($l, $planets[$i]['in_sign_id'], $planets[$i]['in_sign_deg_e']);

                // 互容
                if ($i_ancient['plus'] > 3 && $l_ancient['plus'] > 3 && $i < $l)
                {
                    $ancient1 = '';
                    if ($i_ancient['walls'] == 1) $ancient1 .= '+本垣';
                    if ($i_ancient['promote'] == 1) $ancient1 .= '+擢升';
                    if ($i_ancient['trisection'] == 1) $ancient1 .= '+三分';
                    if ($i_ancient['extent'] == 1) $ancient1 .= '+界主';
                    if ($i_ancient['period'] == 1) $ancient1 .= '+十度';
                    $ancient1 = mb_substr($ancient1, 1);
                    $ancient2 = '';
                    if ($l_ancient['walls'] == 1) $ancient2 .= '+本垣';
                    if ($l_ancient['promote'] == 1) $ancient2 .= '+擢升';
                    if ($l_ancient['trisection'] == 1) $ancient2 .= '+三分';
                    if ($l_ancient['extent'] == 1) $ancient2 .= '+界主';
                    if ($l_ancient['period'] == 1) $ancient2 .= '+十度';
                    $ancient2 = mb_substr($ancient2, 1);
                    if (isset($planets[$i]['phase'][$i . '-' . $l]) || isset($planets[$i]['phase'][$l . '-' . $i]))
                        $have_phase = true;
                    else
                        $have_phase = false;
                    $miscible[] = $i . '-' . $l;
                    $miscible[] = $l . '-' . $i;
                    $ret[2][] = [
                        'id1' => $i,
                        'ancient1' => $ancient2,
                        'id2' => $l,
                        'ancient2' => $ancient1,
                        'phase' => $have_phase,// 是否成相位
                        'relation_by' => [
                            'walls1' => $i_ancient['walls'],
                            'promote1' => $i_ancient['promote'],
                            'trisection1' => $i_ancient['trisection'],
                            'extent1' => $i_ancient['extent'],
                            'period1' => $i_ancient['period'],
                            'walls2' => $l_ancient['walls'],
                            'promote2' => $l_ancient['promote'],
                            'trisection2' => $l_ancient['trisection'],
                            'extent2' => $l_ancient['extent'],
                            'period2' => $l_ancient['period'],
                        ],
                        'relation' => '互容',
                        'status' => 2,
                    ];
                } elseif (isset($planets[$i]['phase'][$i . '-' . $l]) && $l_ancient['plus'] > 3)
                {
                    // 没有互溶 和 接纳
                    if (!in_array($i . '-' . $l, $miscible) && !in_array($i . '-' . $l, $accept))
                    {
                        // 存在相位  接纳
                        $ancient2 = '';
//                        $ancient1 = '';
                        if ($l_ancient['walls'] == 1) $ancient2 .= '+本垣';
                        if ($l_ancient['promote'] == 1) $ancient2 .= '+擢升';
                        if ($l_ancient['trisection'] == 1) $ancient2 .= '+三分';
                        if ($l_ancient['extent'] == 1) $ancient2 .= '+界主';
                        if ($l_ancient['period'] == 1) $ancient2 .= '+十度';
                        $ancient2 = mb_substr($ancient2, 1);

                        $accept[] = $i . '-' . $l;
                        $ret[1][] = [
                            'id1' => $i,
                            'ancient1' => '',
                            'id2' => $l,
                            'ancient2' => $ancient2,
                            'relation_by' => [
                                'walls' => $l_ancient['walls'], 'promote' => $l_ancient['promote'], 'trisection' => $l_ancient['trisection'],
                                'extent' => $l_ancient['extent'], 'period' => $l_ancient['period']
                            ],
                            'relation' => '接纳',
                            'status' => 1,
                        ];
                    }
                } elseif (isset($planets[$l]['phase'][$l . '-' . $i]) && $i_ancient['plus'] > 3)
                {
                    // 没有互容 和 接纳
                    if (!in_array($l . '-' . $i, $miscible) && !in_array($l . '-' . $i, $accept))
                    {
                        // 存在相位  接纳
//                        $ancient2 = '';
                        $ancient1 = '';
                        if ($i_ancient['walls'] == 1) $ancient1 .= '+本垣';
                        if ($i_ancient['promote'] == 1) $ancient1 .= '+擢升';
                        if ($i_ancient['trisection'] == 1) $ancient1 .= '+三分';
                        if ($i_ancient['extent'] == 1) $ancient1 .= '+界主';
                        if ($i_ancient['period'] == 1) $ancient1 .= '+十度';
                        $ancient1 = mb_substr($ancient1, 1);
                        $accept[] = $l . '-' . $i;
                        $ret[1][] = [
                            'id1' => $l,
                            'ancient1' => '',
                            'id2' => $i,
                            'ancient2' => $ancient1,
                            'relation_by' => [
                                'walls' => $i_ancient['walls'], 'promote' => $i_ancient['promote'], 'trisection' => $i_ancient['trisection'],
                                'extent' => $i_ancient['extent'], 'period' => $i_ancient['period']
                            ],
                            'relation' => '接纳',
                            'status' => 1,
                        ];
                    }
                }
            }
        }
        // 古典七星
        for ($i = 0; $i <= 6; $i++)
        {
            // 所有星座的29° 岐度
            if ($planets[$i]['ancient']['diversity'])
            {
                $ret[3][] = [
                    'id1' => $i,
                    'id2' => -1,
                    'event' => '位于岐度',
                    'status' => 3,
                ];
            }
            // 紧要度数
            if ($planets[$i]['ancient']['vital'])
            {
                $ret[4][] = [
                    'id1' => $i,
                    'id2' => -1,
                    'event' => '位于紧要度数',
                    'status' => 4,
                ];
            }
            // 缺点度数
            if ($planets[$i]['ancient']['defect'])
            {
                $ret[5][] = [
                    'id1' => $i,
                    'id2' => -1,
                    'event' => '位于缺点度数',
                    'status' => 5,
                ];
            }
            // 映点
            if (!empty($planets[$i]['ancient']['antipode']['antipode_planet']) && $i < $planets[$i]['ancient']['antipode']['antipode_planet'][0])
            {
                $ret[6][] = [
                    'id1' => $i,
                    'id2' => $planets[$i]['ancient']['antipode']['antipode_planet'][0],
                    'event' => '成映点',
                    'status' => 6,
                ];
            }
            // 成反映点
            if (!empty($planets[$i]['ancient']['antipode']['reflect_planet']) && $i < $planets[$i]['ancient']['antipode']['reflect_planet'][0])
            {
                $ret[7][] = [
                    'id1' => $i,
                    'id2' => $planets[$i]['ancient']['antipode']['reflect_planet'][0],
                    'event' => '成反映点',
                    'status' => 7,
                ];
            }
            // 燃烧之路
            if ($planets[$i]['ancient']['burn_way'])
            {
                $ret[8][] = [
                    'id1' => $i,
                    'id2' => -1,
                    'event' => '位于燃烧之路',
                    'status' => 8,
                ];
            }
        }
        return $ret;
    }

    /**
     * 计算阿拉伯点
     * @param array $planets
     * @param array $houses
     * @param bool $day
     * @return array
     */
    protected function getTheArabics($planets = [], $houses = [], $day = true)
    {
//        $ret = [];
        if ($day)
        {
            $fortune = $houses[1]['deg'] + $planets[1]['deg'] - $planets[0]['deg'];
            $spirit = $houses[1]['deg'] + $planets[0]['deg'] - $planets[1]['deg'];
            $children = $planets[6]['deg'] - $planets[5]['deg'] + $houses[1]['deg'];
            $knowledge = $houses[1]['deg'] + $planets[1]['deg'] - $planets[2]['deg'];
        } else
        {
            $fortune = $houses[1]['deg'] + $planets[0]['deg'] - $planets[1]['deg'];
            $spirit = $houses[1]['deg'] + $planets[1]['deg'] - $planets[0]['deg'];
            $children = $planets[5]['deg'] - $planets[6]['deg'] + $houses[1]['deg'];
            $knowledge = $houses[1]['deg'] + $planets[2]['deg'] - $planets[1]['deg'];
        }
        $marriage = $houses[1]['deg'] + $houses[7]['deg'] - $planets[3]['deg'];
        if ($fortune >= 360) $fortune -= 360;
        elseif ($fortune < 0) $fortune += 360;
        if ($spirit >= 360) $spirit -= 360;
        elseif ($spirit < 0) $spirit += 360;
        if ($children >= 360) $children -= 360;
        elseif ($children < 0) $children += 360;
        if ($knowledge >= 360) $knowledge -= 360;
        elseif ($knowledge < 0) $knowledge += 360;
        if ($marriage >= 360) $marriage -= 360;
        elseif ($marriage < 0) $marriage += 360;

        $ret = [
            0 => [
                'name' => '福点',
                'deg' => $fortune,
                'in_sign_deg' => $this->inSignDeg($fortune),
                'in_sign_id' => ceil($fortune / 30),
            ],
            1 => [
                'name' => '精神点',
                'deg' => $spirit,
                'in_sign_deg' => $this->inSignDeg($spirit),
                'in_sign_id' => ceil($spirit / 30),
            ],
            2 => [
                'name' => '子女点',
                'deg' => $children,
                'in_sign_deg' => $this->inSignDeg($children),
                'in_sign_id' => ceil($children / 30),
            ],
            3 => [
                'name' => '知识点',
                'deg' => $knowledge,
                'in_sign_deg' => $this->inSignDeg($knowledge),
                'in_sign_id' => ceil($knowledge / 30),
            ],
            4 => [
                'name' => '婚姻点',
                'deg' => $marriage,
                'in_sign_deg' => $this->inSignDeg($marriage),
                'in_sign_id' => ceil($marriage / 30),
            ],
        ];
        return $ret;
    }

    /**
     * 相位出入相
     * @param $asp int 相位度数
     * @param $deg1 float 行星度数1
     * @param $deg2 float 行星度数2
     * @param $speed1  float 速度1
     * @param $speed2 float 速度2
     * @param int $phase_orb 实际相位容许度
     * @param int $vs 1=>行星1为本命 2=> 行星2为本命     本命盘速度为0
     * @return bool true 为入相  false 为出相
     */
    protected function phase_in_or_out($asp, $deg1, $deg2, $speed1, $speed2, $phase_orb = 0, $vs = 0)
    {
        // VS 本命盘计算出入相位
        if ($vs)
        {
            if ($vs == 1)
            {
                $speed1 = 0;
            } else
            {
                $speed2 = 0;
            }
        }
        // 方向 1 =>顺行  -1 => 逆行
        $direction = 1;

        if (abs($speed1) > abs($speed2))
        {
            // 计算速度慢的一方的精准成相的度数
            $accurate_a = mod360($deg2 + $asp);
            $accurate_b = mod360($deg2 - $asp);
            $caclDeg = $deg1;

            if ($speed1 < 0)
            {
                $direction = -1;
            }
        } else
        {
            // 计算速度慢的一方的精准成相的度数
            $accurate_a = mod360($deg1 + $asp);
            $accurate_b = mod360($deg1 - $asp);
            $caclDeg = $deg2;

            if ($speed2 < 0)
            {
                $direction = -1;
            }
        }
        $accurate_a = floatval(number_format($accurate_a, 4));
        $accurate_b = floatval(number_format($accurate_b, 4));

        $change = floatval(number_format(mod360($caclDeg + $phase_orb * $direction), 4));

        if ($change == $accurate_a || $change == $accurate_b)
        {
            return true;
        }

        return false;
    }

    /**
     * 获取行星结构
     * @param array $base_data
     * @param bool $is_in
     * @return array
     */
    public function get_structure($base_data = [], $is_in = false)
    {
        if (empty($base_data)) return [];
        $base_data['structure'] = $this->aspect_patterns($base_data, $is_in);
        $base_data['structure']['asterism'] = $this->asterism($base_data);
        $base_data['structure']['midpoint'] = $this->planet_midpoint($base_data);
        $base_data['structure']['finger'] = $this->god_finger($base_data);
        return $base_data;
    }

    /**
     * 大三角
     * 120°-120°-120°
     * 小三角 与两颗星都成60度的这颗星称为顶星
     * 120°-60°-60°
     * T三角 与两星成90度的星体称为“T顶点”
     * 180°-90°-90°
     * 桥三角：两颗星180度，同时有第三颗星与两星分别成60度和120度。该星称为桥星。
     * 180°-60°-120°
     * 大十字：四颗星组成一个正四方形，每颗星都与另外两颗成90度（可以认为是在T三角基础上，加上一颗与T顶点对冲的行星）
     * 180°-90°-90°-180°
     * 大信封：桥三角的桥星对面多出一颗对冲的行星
     * 大风筝：大三角顶星的对面，多出一颗与它成180度的行星
     * @param array $base_data
     * @param bool $is_in
     * @return array
     */
    protected function aspect_patterns($base_data = [], $is_in = false)
    {
        $ret = [
            'trine' => [],
            'small_triangle' => [],
            'kite' => [],
            't_square' => [],
            'cross' => [],
            'bridge_triangle' => [],
            'envelop' => [],
        ];
        for ($i = 0; $i < 10; $i++)
        {
            $a = $base_data['planets'][$i];
            $phasei = $a['phase'];
            for ($j = 0; $j < 10; $j++)
            {
                $b = $base_data['planets'][$j];
                $phasej = $b['phase'];
                // 大三角 + 小三角
                if (isset($phasei[$i . "-" . $j]) && $phasei[$i . "-" . $j]['phase_e'] == 120 && $i < $j)
                {
                    for ($z = 0; $z < 10; $z++)
                    {
                        $c = $base_data['planets'][$z];
                        // 大三角
                        if (isset($phasei[$i . "-" . $z]) && $phasei[$i . "-" . $z]['phase_e'] == 120 && $j < $z
                            && isset($phasej[$j . "-" . $z]) && $phasej[$j . "-" . $z]['phase_e'] == 120)
                        {
                            if ($is_in) $ret['trine'][] = [$i, $j, $z];
                            else $ret['trine'][] = [
                                [
                                    'id' => $i,
                                    'in_sign_id' => $a['in_sign_id'],
                                    'in_house_id' => $a['in_house_id'],
                                ],
                                [
                                    'id' => $j,
                                    'in_sign_id' => $b['in_sign_id'],
                                    'in_house_id' => $b['in_house_id'],
                                ],
                                [
                                    'id' => $z,
                                    'in_sign_id' => $c['in_sign_id'],
                                    'in_house_id' => $c['in_house_id'],
                                ],
                            ];
                            for ($y = 0; $y < 10; $y++)
                            {
                                $d = $base_data['planets'][$y];
                                $phasey = $d['phase'];
                                // 大风筝：大三角顶星的对面，多出一颗与它成180度的行星
                                if (isset($phasey[$y . "-" . $z]) && $phasey[$y . "-" . $z]['phase_e'] == 180)
                                {
                                    if ($is_in) $ret['kite'][] = [$i, $j, $z, $y];
                                    else $ret['kite'][] = [
                                        [
                                            'id' => $i,
                                            'in_sign_id' => $a['in_sign_id'],
                                            'in_house_id' => $a['in_house_id'],
                                            'top' => false,
                                        ],
                                        [
                                            'id' => $j,
                                            'in_sign_id' => $b['in_sign_id'],
                                            'in_house_id' => $b['in_house_id'],
                                            'top' => false,
                                        ],
                                        [
                                            'id' => $z,
                                            'in_sign_id' => $c['in_sign_id'],
                                            'in_house_id' => $c['in_house_id'],
                                            'top' => false,
                                        ],
                                        [
                                            'id' => $y,
                                            'in_sign_id' => $d['in_sign_id'],
                                            'in_house_id' => $d['in_house_id'],
                                            'top' => true,
                                        ],
                                    ];
                                }
                            }
                        } // 小三角
                        elseif (isset($phasei[$i . "-" . $z]) && $phasei[$i . "-" . $z]['phase_e'] == 60 && $j < $z
                            && isset($phasej[$j . "-" . $z]) && $phasej[$j . "-" . $z]['phase_e'] == 60)
                        {
                            if ($is_in) $ret['small_triangle'][] = [$i, $j, $z];
                            else
                                $ret['small_triangle'][] = [
                                    [
                                        'id' => $i,
                                        'in_sign_id' => $a['in_sign_id'],
                                        'in_house_id' => $a['in_house_id'],
                                        'top' => false,
                                    ],
                                    [
                                        'id' => $j,
                                        'in_sign_id' => $b['in_sign_id'],
                                        'in_house_id' => $b['in_house_id'],
                                        'top' => false,
                                    ],
                                    [
                                        'id' => $z,
                                        'in_sign_id' => $c['in_sign_id'],
                                        'in_house_id' => $c['in_house_id'],
                                        'top' => true,
                                    ]
                                ];
                        }

                    }
                } // T三角 + 大十字
                elseif (isset($phasei[$i . "-" . $j]) && $phasei[$i . "-" . $j]['phase_e'] == 180 && $i < $j)
                {
                    for ($z = 0; $z < 10; $z++)
                    {
                        $c = $base_data['planets'][$z];
                        $phasez = $c['phase'];
                        // T三角
                        if (isset($phasei[$i . "-" . $z]) && $phasei[$i . "-" . $z]['phase_e'] == 90 && $i != $z
                            && isset($phasej[$j . "-" . $z]) && $phasej[$j . "-" . $z]['phase_e'] == 90 && $j != $z
                        )
                        {
                            if ($is_in) $ret['t_square'][] = [$i, $j, $z];
                            else
                                $ret['t_square'][] = [
                                    [
                                        'id' => $i,
                                        'in_sign_id' => $a['in_sign_id'],
                                        'in_house_id' => $a['in_house_id'],
                                        'top' => false,
                                    ],
                                    [
                                        'id' => $j,
                                        'in_sign_id' => $b['in_sign_id'],
                                        'in_house_id' => $b['in_house_id'],
                                        'top' => false,
                                    ],
                                    [
                                        'id' => $z,
                                        'in_sign_id' => $c['in_sign_id'],
                                        'in_house_id' => $c['in_house_id'],
                                        'top' => true,
                                    ]
                                ];
                            for ($y = 0; $y < 10; $y++)
                            {
                                $d = $base_data['planets'][$y];
                                $phasey = $d['phase'];

                                // 大十字
                                if (isset($phasey[$y . "-" . $z]) && $phasey[$y . "-" . $z]['phase_e'] == 180 && $i < $z
                                    && isset($phasey[$y . "-" . $j]) && $phasey[$y . "-" . $j]['phase_e'] == 90
                                    && isset($phasey[$y . "-" . $i]) && $phasey[$y . "-" . $i]['phase_e'] == 90 && $z < $y
                                )
                                {
                                    if ($is_in) $ret['cross'][] = [$i, $j, $z];
                                    else
                                        $ret['cross'][] = [
                                            [
                                                'id' => $i,
                                                'in_sign_id' => $a['in_sign_id'],
                                                'in_house_id' => $a['in_house_id'],
                                                'top' => false,
                                            ],
                                            [
                                                'id' => $j,
                                                'in_sign_id' => $b['in_sign_id'],
                                                'in_house_id' => $b['in_house_id'],
                                                'top' => false,
                                            ],
                                            [
                                                'id' => $z,
                                                'in_sign_id' => $c['in_sign_id'],
                                                'in_house_id' => $c['in_house_id'],
                                                'top' => false,
                                            ],
                                            [
                                                'id' => $y,
                                                'in_sign_id' => $d['in_sign_id'],
                                                'in_house_id' => $d['in_house_id'],
                                                'top' => true,
                                            ],
                                        ];
                                }
                            }
                        }
                        // 桥三角 两颗星180度，同时有第三颗星与两星分别成60度和120度。该星称为桥星。
                        // 大信封：桥三角的桥星对面多出一颗对冲的行星
                        elseif ($i != $z && $j != $z &&
                            ((isset($phasez[$z . "-" . $i]) && $phasez[$z . "-" . $i]['phase_e'] == 120
                                    && isset($phasez[$z . "-" . $j]) && $phasez[$z . "-" . $j]['phase_e'] == 60)
                                || (isset($phasez[$z . "-" . $i]) && $phasez[$z . "-" . $i]['phase_e'] == 60
                                    && isset($phasez[$z . "-" . $j]) && $phasez[$z . "-" . $j]['phase_e'] == 120))
                        )
                        {
                            if ($is_in) $ret['bridge_triangle'][] = [$i, $j, $z];
                            else
                                $ret['bridge_triangle'][] = [
                                    [
                                        'id' => $i,
                                        'in_sign_id' => $a['in_sign_id'],
                                        'in_house_id' => $a['in_house_id'],
                                        'top' => false,
                                    ],
                                    [
                                        'id' => $j,
                                        'in_sign_id' => $b['in_sign_id'],
                                        'in_house_id' => $b['in_house_id'],
                                        'top' => false,
                                    ],
                                    [
                                        'id' => $z,
                                        'in_sign_id' => $c['in_sign_id'],
                                        'in_house_id' => $c['in_house_id'],
                                        'top' => true,
                                    ],
                                ];
                            for ($y = 0; $y < 10; $y++)
                            {
                                $d = $base_data['planets'][$y];
                                $phasey = $d['phase'];
                                // 大信封
                                if (isset($phasey[$y . "-" . $z]) && $phasey[$y . "-" . $z]['phase_e'] == 180
                                    && $z < $y && $i < $z
                                )
                                {
                                    if ($is_in) $ret['envelop'][] = [$i, $j, $z];
                                    else
                                        $ret['envelop'][] = [
                                            [
                                                'id' => $i,
                                                'in_sign_id' => $a['in_sign_id'],
                                                'in_house_id' => $a['in_house_id'],
                                            ],
                                            [
                                                'id' => $j,
                                                'in_sign_id' => $b['in_sign_id'],
                                                'in_house_id' => $b['in_house_id'],
                                            ],
                                            [
                                                'id' => $z,
                                                'in_sign_id' => $c['in_sign_id'],
                                                'in_house_id' => $c['in_house_id'],
                                            ],
                                            [
                                                'id' => $y,
                                                'in_sign_id' => $d['in_sign_id'],
                                                'in_house_id' => $d['in_house_id'],
                                            ],
                                        ];
                                }
                            }
                        }
                    }
                }
            }
        }
        return $ret;
    }

    /**
     * 星群：三颗以上行星聚拢，称作星群（不计算小行星）
     * 紧密星群1：三颗以上行星，彼此合相
     * 疏松星群2：三颗以上行星，不满足紧密星群条件，但每颗星都有一个合相
     * 分散星群3：三颗以上行星，不满足前两种，但位于同一星座或同一宫位
     * @param array $base_data
     * @return array
     */
    protected function asterism($base_data = [])
    {
        $ret = [];
        $signs_arr = [];
        $houses_arr = [];
        for ($i = 0; $i < 10; $i++)
        {
            $signs_arr[$base_data['planets'][$i]['in_sign_id']][] = $i;
            $houses_arr[$base_data['planets'][$i]['in_house_id']][] = $i;
        }
        $check = [];
        for ($i = 0; $i < 10; $i++)
        {
            $a = $base_data['planets'][$i];

            $phasei = $a['phase'];
            for ($j = 0; $j < 10; $j++)
            {
                $b = $base_data['planets'][$j];
                $phasej = $b['phase'];
                if (isset($phasei[$i . "-" . $j]) && $phasei[$i . "-" . $j]['phase_e'] == 0 && $i < $j)
                {
                    for ($k = 0; $k < 10; $k++)
                    {
                        $c = $base_data['planets'][$k];
                        $phasek = $c['phase'];
                        // 紧密星群：三颗以上行星，彼此合相
                        if (isset($phasei[$i . "-" . $k]) && $phasei[$i . "-" . $k]['phase_e'] == 0 && $j < $k
                            && isset($phasej[$j . "-" . $k]) && $phasej[$j . "-" . $k]['phase_e'] == 0
                        )
                        {
                            $check_str = $i . '-' . $j . '-' . $k;
                            if (!$this->check_in($check_str, $check))
                            {
                                $check[] = $check_str;
                                $ret[1][] = [
                                    [
                                        'id' => $i,
                                        'in_sign_id' => $a['in_sign_id'],
                                        'in_house_id' => $a['in_house_id'],
                                    ],
                                    [
                                        'id' => $j,
                                        'in_sign_id' => $b['in_sign_id'],
                                        'in_house_id' => $b['in_house_id'],
                                    ],
                                    [
                                        'id' => $k,
                                        'in_sign_id' => $c['in_sign_id'],
                                        'in_house_id' => $c['in_house_id'],
                                    ],
                                ];
                            }

                        } // 疏松星群：三颗以上行星，不满足紧密星群条件，但每颗星都有一个合相
                        elseif ($j < $k &&
                            ((isset($phasei[$i . "-" . $k]) && $phasei[$i . "-" . $k]['phase_e'] == 0)
                                || (isset($phasej[$j . "-" . $k]) && $phasej[$j . "-" . $k]['phase_e'] == 0))
                        )
                        {
                            $ss = 0;
                            for ($g = 0; $g < 10; $g++)
                            {
                                $d = $base_data['planets'][$g];
                                if ($k < $g &&
                                    ((isset($phasei[$i . "-" . $g]) && $phasei[$i . "-" . $g]['phase_e'] == 0)
                                        || (isset($phasej[$j . "-" . $g]) && $phasej[$j . "-" . $g]['phase_e'] == 0)
                                        || (isset($phasek[$k . "-" . $g]) && $phasek[$k . "-" . $g]['phase_e'] == 0))
                                )
                                {
                                    $check_str = $i . '-' . $j . '-' . $k . '-' . $g;
                                    if (!$this->check_in($check_str, $check))
                                    {
                                        $check[] = $check_str;
                                        $ss = 1;
                                        $ret[2][] = [
                                            [
                                                'id' => $i,
                                                'in_sign_id' => $a['in_sign_id'],
                                                'in_house_id' => $a['in_house_id'],
                                            ],
                                            [
                                                'id' => $j,
                                                'in_sign_id' => $b['in_sign_id'],
                                                'in_house_id' => $b['in_house_id'],
                                            ],
                                            [
                                                'id' => $k,
                                                'in_sign_id' => $c['in_sign_id'],
                                                'in_house_id' => $c['in_house_id'],
                                            ],
                                            [
                                                'id' => $g,
                                                'in_sign_id' => $d['in_sign_id'],
                                                'in_house_id' => $d['in_house_id'],
                                            ],
                                        ];
                                    }
                                }
                            }
                            if ($ss == 0)
                            {
                                $check_str = $i . '-' . $j . '-' . $k;
                                if (!$this->check_in($check_str, $check))
                                {
                                    $check[] = $check_str;
                                    $ret[2][] = [
                                        [
                                            'id' => $i,
                                            'in_sign_id' => $a['in_sign_id'],
                                            'in_house_id' => $a['in_house_id'],
                                        ],
                                        [
                                            'id' => $j,
                                            'in_sign_id' => $b['in_sign_id'],
                                            'in_house_id' => $b['in_house_id'],
                                        ],
                                        [
                                            'id' => $k,
                                            'in_sign_id' => $c['in_sign_id'],
                                            'in_house_id' => $c['in_house_id'],
                                        ],
                                    ];
                                }
                            }
                        }
                    }
                }
            }
        }
        // 分散星群 ：三颗或以上行星，不满足前两种，但位于同一星座或同一宫位
        for ($i_i = 1; $i_i < 13; $i_i++)
        {
            $c_s = (isset($signs_arr[$i_i]) && count($signs_arr[$i_i])) ? count($signs_arr[$i_i]) : 0;
            $c_h = (isset($houses_arr[$i_i]) && count($houses_arr[$i_i])) ? count($houses_arr[$i_i]) : 0;
            // 位于同一星座
            if ($c_s >= 3)
            {
                $a = $base_data['planets'][$signs_arr[$i_i][0]];
                $b = $base_data['planets'][$signs_arr[$i_i][1]];
                $c = $base_data['planets'][$signs_arr[$i_i][2]];
                $data = [
                    [
                        'id' => $signs_arr[$i_i][0],
                        'in_sign_id' => $a['in_sign_id'],
                        'in_house_id' => $a['in_house_id'],
                    ],
                    [
                        'id' => $signs_arr[$i_i][1],
                        'in_sign_id' => $b['in_sign_id'],
                        'in_house_id' => $b['in_house_id'],
                    ],
                    [
                        'id' => $signs_arr[$i_i][2],
                        'in_sign_id' => $c['in_sign_id'],
                        'in_house_id' => $c['in_house_id'],
                    ]
                ];
                $check_str = $signs_arr[$i_i][0] . '-' . $signs_arr[$i_i][1] . '-' . $signs_arr[$i_i][2];
                if ($c_s > 3)
                {
                    for ($s = 3; $s < $c_s; $s++)
                    {
                        $check_str .= '-' . $signs_arr[$i_i][$s];
                        $temp = $base_data['planets'][$signs_arr[$i_i][$s]];
                        $data[] = [
                            'id' => $signs_arr[$i_i][$s],
                            'in_sign_id' => $temp['in_sign_id'],
                            'in_house_id' => $temp['in_house_id'],
                        ];
                    }
                }
                if (!$this->check_in($check_str, $check))
                {
                    $data = $this->reset_sort($check_str, $data, 'in_house_id', $base_data);
                    // 同一星座的  按照宫位id排序
                    $check[] = $check_str;
                    $ret[3][] = $data;
                    unset($signs_arr[$i_i]);
                }
            }
            // 位于同一宫位
            if ($c_h >= 3)
            {
                $a = $base_data['planets'][$houses_arr[$i_i][0]];
                $b = $base_data['planets'][$houses_arr[$i_i][1]];
                $c = $base_data['planets'][$houses_arr[$i_i][2]];
                $data = [
                    [
                        'id' => $houses_arr[$i_i][0],
                        'in_sign_id' => $a['in_sign_id'],
                        'in_house_id' => $a['in_house_id'],
                    ],
                    [
                        'id' => $houses_arr[$i_i][1],
                        'in_sign_id' => $b['in_sign_id'],
                        'in_house_id' => $b['in_house_id'],
                    ],
                    [
                        'id' => $houses_arr[$i_i][2],
                        'in_sign_id' => $c['in_sign_id'],
                        'in_house_id' => $c['in_house_id'],
                    ]
                ];
                $check_str = $houses_arr[$i_i][0] . '-' . $houses_arr[$i_i][1] . '-' . $houses_arr[$i_i][2];
                if ($c_h > 3)
                {
                    for ($s = 3; $s < $c_h; $s++)
                    {

                        $check_str .= '-' . $houses_arr[$i_i][$s];
                        $temp = $base_data['planets'][$houses_arr[$i_i][$s]];
                        $data[] = [
                            'id' => $houses_arr[$i_i][$s],
                            'in_sign_id' => $temp['in_sign_id'],
                            'in_house_id' => $temp['in_house_id'],
                        ];
                    }
                }
                if (!$this->check_in($check_str, $check))
                {
                    $data = $this->reset_sort($check_str, $data, 'in_sign_id', $base_data);
                    // 同一宫位的  按照星座id排序
                    unset($houses_arr[$i_i]);
                    $check[] = $check_str;
                    $ret[3][] = $data;

                }
            }
        }

        return $ret;
    }

    /**
     * 计算行星中点(包括四轴)
     * @param array $base_data
     * @return array
     */
    protected function planet_midpoint($base_data = [])
    {
        $ret = [];
        for ($i = 0; $i < 10; $i++)
        {
            $a = $base_data['planets'][$i];

            $deg1 = $a['deg'];
            for ($j = $i + 1; $j < 10; $j++)
            {
                $b = $base_data['planets'][$j];
                $deg2 = $b['deg'];
                $mid = ($deg1 + $deg2) / 2;// 中点度数 (A+B)/2
                for ($k = 0; $k < 10; $k++)
                {
                    $c = $base_data['planets'][$k];
                    $deg3 = $c['deg'];
                    $diff = abs($deg3 - $mid); // 计算相差度数
                    if ($diff > 180) $diff = 360 - $diff;
                    // 判断是否与行星形成 0°/90°/180°相位
                    if ($i != $k && $j != $k
                        && (($diff <= 1) || ($diff > 89 && $diff < 91) || ($diff > 179 && $diff < 181)))
                    {
                        $ret[] = [
                            'id1' => $i,
                            'in_sign_id1' => $a['in_sign_id'],
                            'in_house_id1' => $a['in_house_id'],
                            'id2' => $j,
                            'in_sign_id2' => $b['in_sign_id'],
                            'in_house_id2' => $b['in_house_id'],
                            'id3' => $k,
                            'in_sign_id3' => $c['in_sign_id'],
                            'in_house_id3' => $c['in_house_id'],
                            'asp' => $diff,
                        ];
                    }
                }
                $asc = $base_data['houses'][1];
                $mc = $base_data['houses'][10];
                $asc_deg = $asc['deg'];
                $mc_deg = $mc['deg'];
                $axis = [17 => $asc_deg, 20 => $mc_deg];
                foreach ($axis as $ak => $ax)
                {
                    $diff_axis = abs($ax - $mid); // 计算相差度数
                    if ($diff_axis > 180) $diff_axis = 360 - $diff_axis;
                    if (($diff_axis <= 1) || ($diff_axis > 89 && $diff_axis < 91) || ($diff_axis > 179 && $diff_axis < 181))
                    {
                        $insign = $inhouse = null;
                        if ($ak == 17)
                        {
//                            $name3 = '上升';
                            $insign = $asc['in_sign_id'];
                            $inhouse = 1;
//                        }
//                        if($ak==18)
//                        {
//                            $name3 = '天底';
//                            $insign = $ic['in_sign_id'];
//                            $inhouse = 4;
//                        }
//                        if($ak==19)
//                        {
//                            $name3 = '下降';
//                            $insign = $des['in_sign_id'];
//                            $inhouse = 7;
                        }
                        if ($ak == 20)
                        {
//                            $name3 = '天顶';
                            $insign = $mc['in_sign_id'];
                            $inhouse = 10;
                        }
                        $ret[] = [
                            'id1' => $i,
                            'in_sign_id1' => $a['in_sign_id'],
                            'in_house_id1' => $a['in_house_id'],
                            'id2' => $j,
                            'in_sign_id2' => $b['in_sign_id'],
                            'in_house_id2' => $b['in_house_id'],
                            'id3' => $ak,
                            'in_sign_id3' => $insign,
                            'in_house_id3' => $inhouse,
                            'asp' => $diff_axis,
//                            'output'=>$a['name_whole'].' + '.$b['name_whole'].' = '.$name3,
                        ];
                    }
                }
            }
        }
        return $ret;
    }

    /**
     * 上帝手指
     * 150°-150°-60°
     * 2-2-4
     * @param array $base_data
     * @return array
     */
    protected function god_finger($base_data = [])
    {
        $ret = [];
        for ($i = 0; $i < 10; $i++)
        {
            $a = $base_data['planets'][$i];
            $deg1 = $a['deg'];
            for ($j = $i + 1; $j < 10; $j++)
            {
                $b = $base_data['planets'][$j];
                $deg2 = $b['deg'];
                $diff1_2 = abs($deg1 - $deg2); // 计算相差度数1-2
                if ($diff1_2 > 180) $diff1_2 = 360 - $diff1_2;

                if ($diff1_2 > 148 && $diff1_2 < 152)
                {
                    for ($k = 0; $k < 10; $k++)
                    {
                        $c = $base_data['planets'][$k];
                        $deg3 = $c['deg'];
                        $diff1_3 = abs($deg1 - $deg3); // 计算相差度数1-3
                        if ($diff1_3 > 180) $diff1_3 = 360 - $diff1_3;
                        $diff2_3 = abs($deg2 - $deg3); // 计算相差度数2-3
                        if ($diff2_3 > 180) $diff2_3 = 360 - $diff2_3;
                        if ($i != $k && $j != $k
                            && (($diff1_3 > 148 && $diff1_3 < 152 && $diff2_3 > 56 && $diff2_3 < 64)
                                || ($diff1_3 > 56 && $diff1_3 < 64 && $diff2_3 > 148 && $diff2_3 < 152))
                        )
                        {
                            $ret[] = [
                                [
                                    'id' => $i,
                                    'in_sign_id' => $a['in_sign_id'],
                                    'in_house_id' => $a['in_house_id'],
                                    'top' => false,
                                ],
                                [
                                    'id' => $j,
                                    'in_sign_id' => $b['in_sign_id'],
                                    'in_house_id' => $b['in_house_id'],
                                    'top' => false,
                                ],
                                [
                                    'id' => $k,
                                    'in_sign_id' => $c['in_sign_id'],
                                    'in_house_id' => $c['in_house_id'],
                                    'top' => true,
                                ],
                            ];
                        }

                    }
                }

            }
        }
        return $ret;
    }

    /**
     * 检查是否包含
     * @param string $string 如 0-2-6
     * @param array $arr 如 ['0-2-6-9','0-2-3-6']
     * @return bool
     */
    protected function check_in($string = '', $arr = [])
    {
        if (empty($arr)) return false;

        if (in_array($string, $arr)) return true;
        // 将字符串拆分成数组
//        $string_arr = explode('-',$string);
//        foreach ($arr as $a)
//        {
//            $num = 0;
//            $arr_arr = explode('-',$a);
//            foreach ($string_arr as $s)
//            {
//                if(in_array($s,$arr_arr)) $num++;
//            }
//            // 若包含  则立即返回true
//            if(count($string_arr) == $num) return true;
//        }
        return false;
    }

    /**
     * 重新排序
     * @param string $str
     * @param array $data
     * @param string $sort_by
     * @param array $base_data
     * @return array
     */
    protected function reset_sort($str = '', $data = [], $sort_by = 'deg', $base_data = [])
    {
        if ($str == '') return [];
        foreach ($data as $k1 => $d1)
        {
            for ($k2 = $k1 + 1; $k2 < count($data); $k2++)
            {
                if ($base_data['planets'][$data[$k1]['id']][$sort_by] > $base_data['planets'][$data[$k2]['id']][$sort_by])
                {
                    $temp = $data[$k1];// 此处不能用$d1
                    $data[$k1] = $data[$k2];
                    $data[$k2] = $temp;
                }
            }
        }
        return $data;
    }

    /**
     * 行星落宫
     * @param int 1-12
     * @param array $house
     * @return int
     */
    protected function InWhichHouse($longitude = 0, $house = array())
    {
        $house[13]['deg'] = $house[1]['deg'];
        $in_house = 12;
        for ($j = 1; $j <= 12; $j++)
        {
            $pl = $longitude + (1 / 36000);
            $h_now = $house[$j]['deg'];
            $h_next = $house[$j + 1]['deg'];

            if ($j < 12 && $h_now > $h_next)
                if (($pl >= $h_now && $pl < 360) || ($pl < $h_next && $pl >= 0)) $in_house = $j;
            if ($j == 12 && ($h_now > $house[1]['deg']))
                if (($pl >= $h_now && $pl < 360) || ($pl < $house[1]['deg'] && $pl >= 0)) $in_house = $j;
            if (($pl >= $h_now) && ($pl < $h_next && ($j < 12))) $in_house = $j;
            if (($pl >= $h_now) && ($pl < $house[1]['deg']) && ($j == 12)) $in_house = $j;
        }
        return $in_house;
    }

    /**
     * 计算古典七星角宫  果宫   续宫
     * @param $utdatenow
     * @param $utnow
     * @param $longitude
     * @param $latitude
     * @param $details
     * @return array
     */
    protected function get_house_info($utdatenow, $utnow, $longitude, $latitude, $details)
    {
        $ret = $details;

        $exec_str1 = $this->exec_prefix . " -b$utdatenow -ut$utnow -p0123456789 -eswe -house$longitude,$latitude,p -fldj -g, -head";
        $exec_str2 = $this->exec_prefix . " -b$utdatenow -ut$utnow -p0123456789 -eswe -house$longitude,$latitude,w -fldj -g, -head";
        exec($exec_str1, $out1);
        exec($exec_str2, $out2);

        for ($i = 0; $i < 7; $i++)
        {
            $d1 = @explode(',', $out1[$i])[2] * 1;
            $d2 = @explode(',', $out2[$i])[2] * 1;

            $h1 = floor($d1);
            $h2 = floor($d2);

            if ($h1 % 3 == 1) $ret['influence']['p']['angular'][] = $i;
            elseif ($h1 % 3 == 2) $ret['influence']['p']['continues'][] = $i;
            elseif ($h1 % 3 == 0) $ret['influence']['p']['apoklimas'][] = $i;

            if ($h2 % 3 == 1) $ret['influence']['w']['angular'][] = $i;
            elseif ($h2 % 3 == 2) $ret['influence']['w']['continues'][] = $i;
            elseif ($h2 % 3 == 0) $ret['influence']['w']['apoklimas'][] = $i;
        }
        $ret['according'] = ['just' => [], 'reverse' => []];
        $ds = [];
        for ($i = 0; $i < 10; $i++)
        {
            $d = explode(',', $out1[$i])[1] * 1;
            $ds[] = $d;
        }
        foreach ($ds as $k1 => $d1)
        {
            foreach ($ds as $k2 => $d2)
            {
                if ($k1 < $k2 && abs(abs($d1) - abs($d2)) <= 1)
                {
                    // 反纬照
                    if ($d1 * $d2 < 0)
                    {
                        $ret['according']['reverse'][] = [$k1, $k2];
                    } // 纬照
                    else
                    {
                        $ret['according']['just'][] = [$k1, $k2];
                    }
                }
            }
        }
        return $ret;
    }

    /**
     * 计算福点得分
     * @param array $details
     * @param int $year
     * @return array
     */
    protected function get_fort_score($details = [], $year = 1993)
    {
        $sign_score = 0;
        $house_score = 0;
        $phase_score = 0;
        $star_score = 0;
        // 修复本命盘关闭上升星盘无法显示的问题
        $asc = $details['houses'][1]['deg'];
        $sun = $details['planets'][0]['deg'];
        $moon = $details['planets'][1]['deg'];
        $day = ($details['planets'][0]['in_house_id'] > 6) ? true : false;// 是否为日间盘
        $fort = ($day) ? ($asc + $moon - $sun) : ($asc - $moon + $sun);
        if ($fort >= 360) $fort -= 360;
        elseif ($fort < 0) $fort += 360;

        $in_sign_id = InWhichSign($fort);
        $in_sign_deg = $fort - ($in_sign_id - 1) * 30;

        ###################
        // 福点位于金牛座或双鱼座(+5)
        if (in_array($in_sign_id, [2, 12]))
        {
            $sign_score += 5;
        } // 福点在天秤、射手、狮子或巨蟹(+4)
        elseif (in_array($in_sign_id, [7, 9, 5, 4]))
        {
            $sign_score += 4;
        } // 福点在双子(+3)
        elseif ($in_sign_id == 3)
        {
            $sign_score += 3;
        } // 福点在天蝎、摩羯或水瓶(-5)
        elseif (in_array($in_sign_id, [8, 10, 11]))
        {
            $sign_score += 4;
        } // 福点在白羊(0)
        elseif ($in_sign_id == 1)
        {
            $sign_score += 0;
        } // 福点在处女时
        elseif ($in_sign_id == 6)
        {
            // 合金星和木星守护的界(+2)
            if ($in_sign_deg >= 17 && $in_sign_deg < 28)
            {
                $sign_score += 2;
            }
        }
        // 福点合金星和木星界(+6)
        if (
            // 白羊座
            (
                $in_sign_id == 1
                &&
                (
                    ($in_sign_deg >= 0 && $in_sign_deg < 6)
                    || ($in_sign_deg >= 6 && $in_sign_deg < 12)
                )
            )
            ||
            // 金牛座
            (
                $in_sign_id == 2
                &&
                (
                    ($in_sign_deg >= 0 && $in_sign_deg < 8)
                    || ($in_sign_deg >= 14 && $in_sign_deg < 22)
                )
            )
            ||
            // 双子座
            (
                $in_sign_id == 3
                &&
                (
                    ($in_sign_deg >= 12 && $in_sign_deg < 17)
                    || ($in_sign_deg >= 6 && $in_sign_deg < 12)
                )
            )
            ||
            // 巨蟹座
            (
                $in_sign_id == 4
                &&
                (
                    ($in_sign_deg >= 7 && $in_sign_deg < 13)
                    || ($in_sign_deg >= 19 && $in_sign_deg < 26)
                )
            )
            ||
            // 狮子座
            (
                $in_sign_id == 5
                &&
                (
                    ($in_sign_deg >= 0 && $in_sign_deg < 6)
                    || ($in_sign_deg >= 6 && $in_sign_deg < 11)
                )
            )
            ||
            // 天秤座
            (
                $in_sign_id == 7
                &&
                (
                    ($in_sign_deg >= 21 && $in_sign_deg < 28)
                    || ($in_sign_deg >= 14 && $in_sign_deg < 21)
                )
            )
            ||
            // 天蝎座
            (
                $in_sign_id == 8
                &&
                (
                    ($in_sign_deg >= 7 && $in_sign_deg < 11)
                    || ($in_sign_deg >= 19 && $in_sign_deg < 24)
                )
            )
            ||
            // 射手座
            (
                $in_sign_id == 9
                &&
                (
                    ($in_sign_deg >= 12 && $in_sign_deg < 17)
                    || ($in_sign_deg >= 0 && $in_sign_deg < 12)
                )
            )
            ||
            // 摩羯座
            (
                $in_sign_id == 10
                &&
                (
                    ($in_sign_deg >= 14 && $in_sign_deg < 22)
                    || ($in_sign_deg >= 7 && $in_sign_deg < 14)
                )
            )
            ||
            // 水瓶座
            (
                $in_sign_id == 11
                &&
                (
                    ($in_sign_deg >= 7 && $in_sign_deg < 13)
                    || ($in_sign_deg >= 13 && $in_sign_deg < 20)
                )
            )
            ||
            // 双鱼座
            (
                $in_sign_id == 12
                &&
                (
                    ($in_sign_deg >= 0 && $in_sign_deg < 12)
                    || ($in_sign_deg >= 12 && $in_sign_deg < 16)
                )
            )
        )
        {
            $sign_score += 6;
        }
        // 福点部分合土星或火星守护的界(-5)
        if (
            // 白羊座
            (
                $in_sign_id == 1
                &&
                (
                    ($in_sign_deg >= 20 && $in_sign_deg < 25)
                    || ($in_sign_deg >= 25 && $in_sign_deg < 30)
                )
            )
            ||
            // 金牛座
            (
                $in_sign_id == 2
                &&
                (
                    ($in_sign_deg >= 27 && $in_sign_deg < 30)
                    || ($in_sign_deg >= 22 && $in_sign_deg < 27)
                )
            )
            ||
            // 双子座
            (
                $in_sign_id == 3
                &&
                (
                    ($in_sign_deg >= 17 && $in_sign_deg < 24)
                    || ($in_sign_deg >= 24 && $in_sign_deg < 30)
                )
            )
            ||
            // 巨蟹座
            (
                $in_sign_id == 4
                &&
                (
                    ($in_sign_deg >= 0 && $in_sign_deg < 7)
                    || ($in_sign_deg >= 26 && $in_sign_deg < 30)
                )
            )
            ||
            // 狮子座
            (
                $in_sign_id == 5
                &&
                (
                    ($in_sign_deg >= 24 && $in_sign_deg < 30)
                    || ($in_sign_deg >= 11 && $in_sign_deg < 18)
                )
            )
            ||
            // 处女座
            (
                $in_sign_id == 6
                &&
                (
                    ($in_sign_deg >= 21 && $in_sign_deg < 28)
                    || ($in_sign_deg >= 28 && $in_sign_deg < 30)
                )
            )
            ||
            // 天秤座
            (
                $in_sign_id == 7
                &&
                (
                    ($in_sign_deg >= 28 && $in_sign_deg < 30)
                    || ($in_sign_deg >= 0 && $in_sign_deg < 6)
                )
            )
            ||
            // 天蝎座
            (
                $in_sign_id == 8
                &&
                (
                    ($in_sign_deg >= 0 && $in_sign_deg < 7)
                    || ($in_sign_deg >= 24 && $in_sign_deg < 30)
                )
            )
            ||
            // 射手座
            (
                $in_sign_id == 9
                &&
                (
                    ($in_sign_deg >= 26 && $in_sign_deg < 30)
                    || ($in_sign_deg >= 21 && $in_sign_deg < 26)
                )
            )
            ||
            // 摩羯座
            (
                $in_sign_id == 10
                &&
                (
                    ($in_sign_deg >= 26 && $in_sign_deg < 30)
                    || ($in_sign_deg >= 22 && $in_sign_deg < 26)
                )
            )
            ||
            // 水瓶座
            (
                $in_sign_id == 11
                &&
                (
                    ($in_sign_deg >= 20 && $in_sign_deg < 25)
                    || ($in_sign_deg >= 25 && $in_sign_deg < 30)
                )
            )
            ||
            // 双鱼座
            (
                $in_sign_id == 12
                &&
                (
                    ($in_sign_deg >= 19 && $in_sign_deg < 28)
                    || ($in_sign_deg >= 28 && $in_sign_deg < 30)
                )
            )
        )
        {
            $sign_score -= 5;
        }
        ###################


        $in_house_id = $this->InWhichHouse($fort, $details['houses']);
        #########################
        if ($in_house_id == 1 || $in_house_id == 10)
        {
            $house_score += 5;
        } elseif ($in_house_id == 4 || $in_house_id == 7 || $in_house_id == 11)
        {
            $house_score += 4;
        } elseif ($in_house_id == 2 || $in_house_id == 5)
        {
            $house_score += 3;
        } elseif ($in_house_id == 9)
        {
            $house_score += 2;
        } elseif ($in_house_id == 3)
        {
            $house_score += 1;
        } elseif ($in_house_id == 12)
        {
            $house_score -= 5;
        } elseif ($in_house_id == 6 || $in_house_id == 8)
        {
            $house_score -= 4;
        }
        #############################

        if (abs($sun - $fort) > 270)
        {
            if ($sun > $fort) $dist = $fort + 360 - $sun;
            else $dist = $sun + 360 - $fort;
        } else
        {
            $dist = abs($sun - $fort);
        }
        $burn = 0;// 是否灼伤
        if ($dist > 8.5 && $dist <= 15) $burn = 1; // 在日光下 15
        if ($dist > 17 / 60 && $dist <= 8.5) $burn = 2; // 灼伤 8.5
        #########################################
        foreach ($details['planets'] as $i => $p)
        {
            if (in_array($i, [3, 4, 5, 6, 12]))
            {
                $p_deg = $p['deg'];

                $da = abs($p_deg - $fort);
                if ($da > 180) $da = 360 - $da;

                $phases = [0, 60, 90, 120, 180];

                foreach ($phases as $ps)
                {
                    if ($da <= ($ps + $this->options['asps_orb'][$ps]) && $da >= ($ps - $this->options['asps_orb'][$ps]))
                    {
                        if ($i == 3 || $i == 5)
                        {
                            if ($ps == 0) $phase_score += 5;
                            elseif ($ps == 120) $phase_score += 4;
                            elseif ($ps == 60) $phase_score += 3;
                        }
                        if ($i == 12)
                        {
                            if ($ps == 0) $phase_score += 3;
                            elseif ($ps == 180) $phase_score -= 3;
                        }

                        if ($i == 4 || $i == 6)
                        {
                            if ($ps == 180) $phase_score -= 4;
                            elseif ($ps == 0) $phase_score -= 6;
                            elseif ($ps == 60 || $ps == 120) $phase_score -= 2;
                        }
                    }
                }
            }
        }
        if ($burn != 1 && $burn != 2) $phase_score += 5;
        elseif ($burn == 1) $phase_score -= 5;
        #########################################

        ###################################################################
        $diff = ($year * 1 - 2000) * 0.83 / 60;
        // 计算恒星 每一百年移动83′ 每年0.83分
        foreach (config('astrolog.star') as $s)
        {
            $star = $s[0] + $diff;
            // 合恒星
            if (abs($fort - $star) <= 1)
            {
                // 吉凶状态  凶 平 吉 大吉
                if ($s[1] == '轩辕十四') $star_score += 6;
                elseif ($s[1] == '角宿一') $star_score += 5;
                elseif ($s[1] == '大陵五') $star_score -= 6;
                elseif ($s[6] == '吉' || $s[6] == '大吉') $star_score += 4;
                elseif ($s[6] == '凶') $star_score -= 4;

            }
            // 刑恒星
            if (abs($fort - $star) <= 91 && abs($fort - $star) >= 89)
            {
                if ($s[6] == '凶') $star_score -= 3;
            }
            // 冲恒星
            if (abs($fort - $star) <= 181 && abs($fort - $star) >= 179)
            {
                if ($s[6] == '凶') $star_score -= 4;
            }
        }
        ###################################################################
        $total = $sign_score + $house_score + $phase_score + $star_score;
        $ret = ['ecliptic' => $sign_score, 'house' => $house_score, 'phase' => $phase_score, 'star' => $star_score, 'total' => $total];

        return $ret;
    }

    /**
     * 大限、主限运势星
     * @param null $birthtime
     * @param int $years_alive
     * @return array
     */
    protected function getTheMainSubLuck($birthtime = null, $years_alive = 0)
    {
        $astroConfig = config('astrolog');
        // 日间盘
        if ($this->options['day_chart'] == true) $firdaria_main = $astroConfig['firdaria_main_day'];
        // 夜间盘
        else $firdaria_main = $astroConfig['firdaria_main_night_' . $this->options['firdaria']];
        $years_alive_or = $years_alive;
        // 大于75岁 从头开始
        $years_alive = $years_alive - floor($years_alive / 75) * 75;
        $years = $years_temp = 0;
        $time_main = $time_sub = $birthtime;
        $main_luck = $sub_luck = null;

        $ret = [];
        foreach ($firdaria_main as $i => $f)
        {
            $y = $astroConfig['firdaria_planet_years'][$f];
            // 以当前大限主管星为起始星(小限)
            $sub_planets = $this->getTheSubPlanets($f);
            $pro_add_sub = count($sub_planets) == 1 ? $y : $y / 7;//大限平分七份为小限时间  南北交时为全部
            $pro_add_sub_time = $pro_add_sub * 365.2422 * 24 * 3600;

            $sub_details = [];
            foreach ($sub_planets as $j => $s)
            {
                $sub_details[] = [
                    'id' => $s,
                    'cross' => $pro_add_sub,
                    'year_min' => $years_temp,
                    'year_max' => $years_temp + $pro_add_sub,
                    'start' => date("y年m月d日", $time_sub),
                    'end' => date("y年m月d日", $time_sub + $pro_add_sub_time),
                ];
                $years_temp += $pro_add_sub;
                $time_sub += $pro_add_sub_time;

                if ($years_alive <= $years_temp && $sub_luck === null) $sub_luck = $s;
            }
            $ret['details'][] = [
                'main' => [
                    'id' => $f,
                    'cross' => $y,
                    'year_min' => $years,
                    'year_max' => $years + $y,
                    'start' => date("y年m月d日", $time_main),
                    'end' => date("y年m月d日", strtotime("+$y year", $time_main)),
                ],
                'sub' => $sub_details,
            ];
            $years += $y;
            $time_main = strtotime("+$y year", $time_main);

            if ($years_alive <= $years && $main_luck === null) $main_luck = $f;
        }
        $ret['main_luck'] = $main_luck;
        $ret['sub_luck'] = $sub_luck;
        $ret['years_alive'] = $years_alive_or;

        return $ret;
    }

    /**
     * 获取当前小限星 数组
     * @param $main
     * @return array
     */
    protected function getTheSubPlanets($main)
    {
        // 以当前大限主管星为起始星(小限)
        $sub_planets = config('astrolog.firdaria_sub');

        if ($main == 16 || $main == 12)
            return [$main];

        $temp = [];
        $start = false;
        $num = 0;
        foreach ($sub_planets as $s)
        {
            if ($s == $main || $start === true)
            {
                $temp[] = $s;
                $start = true;
                $num++;
                if ($num == 7) break;
            }
        }
        return $temp;
    }

    /**
     * 计算两个时间戳相差月份数
     * @param null integer $time1 开始时间戳
     * @param null integer $time2 结束时间戳
     * @return int 相差月份数
     */
    protected function getTheMonthAgo($time1 = null, $time2 = null)
    {
        if ($time2 < $time1)
        {
//            throw new ApiException('当前选择时间早于出生时间', 200, 0);
            $this->error = '当前选择时间早于出生时间';
            return false;
        }
        $year1 = date("Y", $time1);
        $month1 = date("m", $time1);
        $day1 = date("d", $time1);
        $year2 = date("Y", $time2);
        $month2 = date("m", $time2);
        $day2 = date("d", $time2);

        if ($day2 < $day1)
        {
            $month2--;
        }
        if ($month2 < $month1)
        {
            $month2 += 12;
            $year2--;
        }
        $month = $month2 - $month1 + ($year2 - $year1) * 12;
        return $month;
    }

    /**
     * 获取行星星历数据
     * @param string $p 0123456789DH
     * @return mixed
     */
    public function getPlanetOriginData($p = '0')
    {
        $timestamp = $this->deal_time($this->recode1);
        $utdatenow = strftime("%d.%m.%Y", $timestamp);
        $utnow = strftime("%H:%M:%S", $timestamp);

        $exec_str = $this->exec_prefix . " -b{$utdatenow} -ut{$utnow} -p{$p} -eswe -fl -g, -head";

        exec($exec_str, $out);

        return $out;
    }

    /**
     * 获取星历数据
     * @param array $options
     * @return mixed
     */
    protected function execData($options = [])
    {
        $exec_str = $this->exec_prefix . " -b{$options['utdatenow']} -ut{$options['utnow']} -p0123456789DAmHt -eswe -house{$options['longitude']},{$options['latitude']},{$options['h_sys']} -fldsa -g, -head";

        exec($exec_str, $out);

        if (empty($out) || count($out) < 27)
        {
            unset($out);
            $exec_str = $this->exec_prefix . " -b{$options['utdatenow']} -ut{$options['utnow']} -p0123456789DAmHt -eswe -house{$options['longitude']},{$options['latitude']},w -fldsa -g, -head";

            exec($exec_str, $out);
        }

        return $out;
    }

    /**
     * 计算日月升等信息
     * @return array
     */
    public function getTheRecodeAstro()
    {
        $timestamp = $this->deal_time($this->advance);
        $utdatenow = strftime("%d.%m.%Y", $timestamp);
        $utnow = strftime("%H:%M:%S", $timestamp);

        $longitude = ($this->advance['long_deg'] + $this->advance['long_min'] / 60) * $this->advance['ew'];
        $latitude = ($this->advance['lat_deg'] + $this->advance['lat_min'] / 60) * $this->advance['ns'];

        $options = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out = $this->execData($options);

        $data = $this->getOriginalData($out);

        $result['sun'] = InWhichSign($data['p1'][0]) . '-' . InWhichHouse($data['p1'][0], $data['hc1']) . '-' . $data['p1'][0];
        $result['moon'] = InWhichSign($data['p1'][1]) . '-' . InWhichHouse($data['p1'][1], $data['hc1']) . '-' . $data['p1'][1];
        $result['merc'] = InWhichSign($data['p1'][2]) . '-' . InWhichHouse($data['p1'][2], $data['hc1']) . '-' . $data['p1'][2];
        $result['venu'] = InWhichSign($data['p1'][3]) . '-' . InWhichHouse($data['p1'][3], $data['hc1']) . '-' . $data['p1'][3];
        $result['mars'] = InWhichSign($data['p1'][4]) . '-' . InWhichHouse($data['p1'][4], $data['hc1']) . '-' . $data['p1'][4];
        $result['jupi'] = InWhichSign($data['p1'][5]) . '-' . InWhichHouse($data['p1'][5], $data['hc1']) . '-' . $data['p1'][5];
        $result['satu'] = InWhichSign($data['p1'][6]) . '-' . InWhichHouse($data['p1'][6], $data['hc1']) . '-' . $data['p1'][6];
        $result['non'] = InWhichSign($data['p1'][12]) . '-' . InWhichHouse($data['p1'][12], $data['hc1']) . '-' . $data['p1'][12];
        $result['lili'] = InWhichSign($data['p1'][11]) . '-' . InWhichHouse($data['p1'][11], $data['hc1']) . '-' . $data['p1'][11];
        $result['juno'] = InWhichSign($data['p1'][13]) . '-' . InWhichHouse($data['p1'][13], $data['hc1']) . '-' . $data['p1'][13];
        $result['asc'] = InWhichSign($data['p1'][17]) . '-' . InWhichHouse($data['p1'][17], $data['hc1']) . '-' . $data['p1'][17];
        $result['mc'] = InWhichSign($data['p1'][20]) . '-' . InWhichHouse($data['p1'][20], $data['hc1']) . '-' . $data['p1'][20];

        return $result;
    }

    /**
     * 切换星盘配置
     * @param string $chart 需要切换到的星盘
     */
    protected function switchConfiguration($chart = 'now')
    {
        $this->options['asps_display'] = $this->options['setting'][$chart]['asps_display'];
        $this->options['asps_orb'] = $this->options['setting'][$chart]['asp_orb_all'];
        $this->options['planets_orb'] = $this->options['setting'][$chart]['planet_orb_all'];
        $this->options['planets_display'] = $this->options['setting'][$chart]['planets_display'];
        $this->options['h_sys'] = $this->options['setting'][$chart]['h_sys'];
        if (isset($this->options['setting'][$chart]['firdaria'])) $this->options['firdaria'] = $this->options['setting'][$chart]['firdaria'];
        return;
    }

    /**
     * 获取天象盘数据
     * @return array
     */
    protected function getNowData()
    {
        $timestamp = $this->deal_time($this->advance);
        $utdatenow = strftime("%d.%m.%Y", $timestamp);
        $utnow = strftime("%H:%M:%S", $timestamp);

        $longitude = $this->advance['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude = $this->advance['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $options = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out = $this->execData($options);

        $original_data = $this->getOriginalData($out);

        $this->array_remove($original_data);

        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1'], $this->advance['year']);

        $phase = $this->planetPkPlanet($original_data, $original_data, true);

        foreach ($phase['planets'] as $k => $d)
        {
            $details['planets'][$k]['phase'] = $d['phase'];
            if (empty($d['phase'])) $details['planets'][$k]['phase'] = null;
        }

        $details = $this->get_structure($details);

        // 需要获取画盘所需数据
        if ($this->isAstrolabe === true)
        {
            $details['phase'] = $phase['phase'];
            $details['characteristic'] = $this->recept_or_mutual_recept($details['planets']);
            // 福点分数
            $details['fortune'] = $this->get_fort_score($details, $this->advance['year']);

            $details = $this->get_house_info($utdatenow, $utnow, $longitude, $latitude, $details);
            // 指定输出为object  防止类型改变
            $details['characteristic'] = (object)$details['characteristic'];
            // 指定输出为object  防止所有行星全开时 类型改变
            $details['planets'] = (object)$details['planets'];
        }

        return $details;
    }

    /**
     * 获取本命盘数据
     * @return array
     */
    protected function getNatalData()
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $utdatenow = strftime("%d.%m.%Y", $timestamp1);
        $utnow = strftime("%H:%M:%S", $timestamp1);

        $longitude = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $options = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out = $this->execData($options);

        $original_data = $this->getOriginalData($out);

        $this->array_remove($original_data);

        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1'], $this->recode1['year']);

        $phase = $this->planetPkPlanet($original_data, $original_data, true);

        foreach ($phase['planets'] as $k => $d)
        {
            $details['planets'][$k]['phase'] = $d['phase'];
            if (empty($d['phase'])) $details['planets'][$k]['phase'] = null;
        }

        // 需要获取画盘所需数据
        if ($this->isAstrolabe === true)
        {
            $details['phase'] = $phase['phase'];
            $details['characteristic'] = $this->recept_or_mutual_recept($details['planets']);
            // 福点分数
            $details['fortune'] = $this->get_fort_score($details, $this->recode1['year']);

            $details = $this->get_structure($details);

            $details = $this->get_house_info($utdatenow, $utnow, $longitude, $latitude, $details);
            // 指定输出为object  防止类型改变
            $details['characteristic'] = (object)$details['characteristic'];
            // 指定输出为object  防止所有行星全开时 类型改变
            $details['planets'] = (object)$details['planets'];
        }

        return $details;
    }

    /**
     * 获取行运盘数据
     * @return array
     */
    protected function getTransitsData()
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $utdatenow1 = strftime("%d.%m.%Y", $timestamp1);
        $utnow1 = strftime("%H:%M:%S", $timestamp1);

        $longitude1 = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude1 = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $exec_str = $this->exec_prefix . " -b{$utdatenow1} -ut{$utnow1} -p0 -eswe -house{$longitude1},{$latitude1},{$this->options['h_sys']} -fj -g, -head";
        exec($exec_str, $out);

        $timestamp2 = $this->deal_time($this->advance);
        $utdatenow2 = strftime("%d.%m.%Y", $timestamp2);
        $utnow2 = strftime("%H:%M:%S", $timestamp2);

        // 检测时间
//        if (!$this->checkTime($timestamp1, $timestamp2))
//        {
////            return false;
//        }

        $options1 = ['utdatenow' => $utdatenow1, 'utnow' => $utnow1, 'longitude' => $longitude1, 'latitude' => $latitude1, 'h_sys' => $this->options['h_sys']];
        $options2 = ['utdatenow' => $utdatenow2, 'utnow' => $utnow2, 'longitude' => $longitude1, 'latitude' => $latitude1, 'h_sys' => $this->options['h_sys']];

        $out1 = $this->execData($options1);
        $out2 = $this->execData($options2);

        $original_data1 = $this->getOriginalData($out1);
        $original_data2 = $this->getOriginalData($out2);

        $this->array_remove($original_data1);
        $this->array_remove($original_data2);

        $details1 = $this->getPlanetHouseDetail($original_data1, $original_data1['hc1']);

        $phase1 = $this->planetPkPlanet($original_data1, $original_data2, false, 1);

        foreach ($phase1['planets'] as $k1 => $d1)
        {
            $details1['planets'][$k1]['phase'] = $d1['phase'];
            if (empty($d1['phase'])) $details1['planets'][$k1]['phase'] = null;
        }

        $details2 = $this->getPlanetHouseDetail($original_data2, $original_data1['hc1']);

        $phase2 = $this->planetPkPlanet($original_data2, $original_data1, false, 2);

        foreach ($phase2['planets'] as $k2 => $d2)
        {
            $details2['planets'][$k2]['phase'] = $d2['phase'];
            if (empty($d2['phase'])) $details2['planets'][$k2]['phase'] = null;
        }

        if ($this->isAstrolabe === true)
        {
            $details1['phase'] = $phase1['phase'];
            $details2['phase'] = $phase2['phase'];

            // 指定输出为object  防止所有行星全开时 类型改变
            $details1['planets'] = (object)$details1['planets'];
            $details2['planets'] = (object)$details2['planets'];
        }

        return [$details1, $details2];
    }

    /**
     * 获取三次限数据
     * @param float $coef 默认三限参数27.321661     次限参数365.2422
     * @return array
     */
    protected function getThirdprogressedData($coef = 27.321661)
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $utdatenow = strftime("%d.%m.%Y", $timestamp1);
        $utnow = strftime("%H:%M:%S", $timestamp1);

        $longitude = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $exec_str = $this->exec_prefix . " -b{$utdatenow} -ut{$utnow} -p0 -eswe -house{$longitude},{$latitude},{$this->options['h_sys']} -fj -g, -head";
        exec($exec_str, $out);

        $timestamp2 = $this->deal_time($this->advance);

        // 检测时间
//        if (!$this->checkTime($timestamp1, $timestamp2))
//        {
////            return false;
//        }

        $birth_JD = gregoriantojd(date('m', $timestamp1), date('d', $timestamp1), date('Y', $timestamp1)) + ((date('H', $timestamp1) + (date('i', $timestamp1) / 60)) / 24);
        $start_JD = gregoriantojd(date('m', $timestamp2), date('d', $timestamp2), date('Y', $timestamp2)) + ((date('H', $timestamp2) + (date('i', $timestamp2) / 60)) / 24);

        $days_alive = $start_JD - $birth_JD; // 总天数
        $prog_time_to_add = $days_alive / $coef; // 即本命后第几天

        $time_before_JD = $birth_JD + floor($prog_time_to_add);

        //变化比率 //就是$prog_time_to_add的去掉整数的小数
        $time_change_pro = $prog_time_to_add - floor($prog_time_to_add);

        $date_before = strtotime(jdtogregorian($time_before_JD));
        $date_after = strtotime('+1 day', $date_before);

        $utdatenow1 = strftime("%d.%m.%Y", $date_before);
        $utnow1 = strftime("%H:%M:%S", $timestamp1);

        $utdatenow2 = strftime("%d.%m.%Y", $date_after);
        $utnow2 = strftime("%H:%M:%S", $timestamp1);

        $options1 = ['utdatenow' => $utdatenow1, 'utnow' => $utnow1, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];
        $options2 = ['utdatenow' => $utdatenow2, 'utnow' => $utnow2, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out1 = $this->execData($options1);
        $out2 = $this->execData($options2);

        $calOut = $this->getProgressionThirdprogressed($out1, $out2, $time_change_pro);

        $original_data = $this->getOriginalData($calOut);
        $this->array_remove($original_data);

        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1']);
        $phase = $this->planetPkPlanet($original_data, $original_data, true);

        foreach ($phase['planets'] as $k => $d)
        {
            $details['planets'][$k]['phase'] = $d['phase'];
            if (empty($d['phase'])) $details['planets'][$k]['phase'] = null;
        }

        // 绘制星盘时，不需要结构参数
        if ($this->isAstrolabe === true)
        {
            $details['phase'] = $phase['phase'];
            $details['planets'] = (object)$details['planets'];
            $details['time1'] = date('Y-m-d H:i:s', $date_before);
        } else
        {
            $details = $this->get_structure($details, true);
        }

        return $details;
    }

    /**
     * 获取三次限VS本命盘的数据
     * @param float $coef
     * @return array
     */
    protected function getThirdprogressedVsNatalData($coef = 27.321661)
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $utdatenow = strftime("%d.%m.%Y", $timestamp1);
        $utnow = strftime("%H:%M:%S", $timestamp1);

        $longitude = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $exec_str = $this->exec_prefix . " -b{$utdatenow} -ut{$utnow} -p0 -eswe -house{$longitude},{$latitude},{$this->options['h_sys']} -fj -g, -head";
        exec($exec_str, $out);

        $timestamp2 = $this->deal_time($this->advance);

        // 检测时间
//        if (!$this->checkTime($timestamp1, $timestamp2))
//        {
////            return false;
//        }

        $birth_JD = gregoriantojd(date('m', $timestamp1), date('d', $timestamp1), date('Y', $timestamp1)) + ((date('H', $timestamp1) + (date('i', $timestamp1) / 60)) / 24);
        $start_JD = gregoriantojd(date('m', $timestamp2), date('d', $timestamp2), date('Y', $timestamp2)) + ((date('H', $timestamp2) + (date('i', $timestamp2) / 60)) / 24);
        $days_alive = $start_JD - $birth_JD; // 总天数
        $prog_time_to_add = $days_alive / $coef; // 即本命后第几天

        $time_before_JD = $birth_JD + floor($prog_time_to_add);

        //变化比率 //就是$prog_time_to_add的去掉整数的小数
        $time_change_pro = $prog_time_to_add - floor($prog_time_to_add);

        $date_before = strtotime(jdtogregorian($time_before_JD));
        $date_after = strtotime('+1 day', $date_before);

        $utdatenow1 = strftime("%d.%m.%Y", $date_before);
        $utnow1 = strftime("%H:%M:%S", $timestamp1);

        $utdatenow2 = strftime("%d.%m.%Y", $date_after);
        $utnow2 = strftime("%H:%M:%S", $timestamp1);

        $options1 = ['utdatenow' => $utdatenow1, 'utnow' => $utnow1, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];
        $options2 = ['utdatenow' => $utdatenow2, 'utnow' => $utnow2, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];
        $options3 = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out1 = $this->execData($options1);
        $out2 = $this->execData($options2);
        $out_natal = $this->execData($options3);

        $calOut = $this->getProgressionThirdprogressed($out1, $out2, $time_change_pro);

        $original_data1 = $this->getOriginalData($out_natal);
        $original_data2 = $this->getOriginalData($calOut);
        $this->array_remove($original_data1);
        $this->array_remove($original_data2);
        $details1 = $this->getPlanetHouseDetail($original_data1, $original_data1['hc1']);
        $details2 = $this->getPlanetHouseDetail($original_data2, $original_data1['hc1']);
        $phase1 = $this->planetPkPlanet($original_data1, $original_data2);
        $phase2 = $this->planetPkPlanet($original_data2, $original_data1);
        foreach ($phase1['planets'] as $k1 => $d1)
        {
            $details1['planets'][$k1]['phase'] = $d1['phase'];
            if (empty($d1['phase'])) $details1['planets'][$k1]['phase'] = null;
        }
        foreach ($phase2['planets'] as $k2 => $d2)
        {
            $details2['planets'][$k2]['phase'] = $d2['phase'];
            if (empty($d2['phase'])) $details2['planets'][$k2]['phase'] = null;
        }

        if ($this->isAstrolabe === true)
        {
            $details1['phase'] = $phase1['phase'];
            $details2['phase'] = $phase2['phase'];
            $details1['planets'] = (object)$details1['planets'];// 指定输出为object  防止所有行星全开时 类型改变
            $details2['planets'] = (object)$details2['planets'];// 指定输出为object  防止所有行星全开时 类型改变

            $details['time1'] = date('Y-m-d H:i:s', $date_before);
        }

        return [$details1, $details2];
    }

    /**
     * 获取太阳弧盘数据
     * @return array
     */
    protected function getSolarData()
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $longitude = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $timestamp2 = $this->deal_time($this->advance);

        // 检测时间
//        if (!$this->checkTime($timestamp1, $timestamp2))
//        {
////            return false;
//        }

        $birth_JD = gregoriantojd(date('m', $timestamp1), date('d', $timestamp1), date('Y', $timestamp1)) - 0.5 + ((date('H', $timestamp1) + (date('i', $timestamp1) / 60)) / 24);
        $start_JD = gregoriantojd(date('m', $timestamp2), date('d', $timestamp2), date('Y', $timestamp2)) - 0.5 + ((date('H', $timestamp2) + (date('i', $timestamp2) / 60)) / 24);
        $days_alive = $start_JD - $birth_JD; // 总天数
        $prog_time_to_add = $days_alive / 365.2422;// 365.2422  365.2421990  365.25

        $jd_to_use = $birth_JD + $prog_time_to_add;

        $utdatenow1 = strftime("%d.%m.%Y", $timestamp1);
        $utnow1 = strftime("%H:%M:%S", $timestamp1);


        $options1 = ['utdatenow' => $utdatenow1, 'utnow' => $utnow1, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out1 = $this->execData($options1);

        $exec_str2 = $this->exec_prefix . " -bj{$jd_to_use} -ut -p0 -eswe -fl -g, -head";

        exec($exec_str2, $out2);
        $original_data1 = $this->getOriginalData($out1);

        $this->array_remove($original_data1);

        $p_sun = $out2[0];
        $original_data2 = $this->getTheLongitudeBySolarArc($p_sun, $original_data1);

        $details1 = $this->getPlanetHouseDetail($original_data1, $original_data1['hc1']);
        $details2 = $this->getPlanetHouseDetail($original_data2, $original_data1['hc1']);
        $phase1 = $this->planetPkPlanet($original_data1, $original_data2, false, 1);
        foreach ($phase1['planets'] as $k1 => $d1)
        {
            $details1['planets'][$k1]['phase'] = $d1['phase'];
            if (empty($d1['phase'])) $details1['planets'][$k1]['phase'] = null;
        }

        $phase2 = $this->planetPkPlanet($original_data2, $original_data1, false, 2);
        foreach ($phase2['planets'] as $k2 => $d2)
        {
            $details2['planets'][$k2]['phase'] = $d2['phase'];
            if (empty($d2['phase'])) $details2['planets'][$k2]['phase'] = null;
        }

        if ($this->isAstrolabe === true)
        {
            $details1['phase'] = $phase1['phase'];
            $details2['phase'] = $phase2['phase'];
            $details1['planets'] = (object)$details1['planets'];// 指定输出为object  防止所有行星全开时 类型改变
            $details2['planets'] = (object)$details2['planets'];// 指定输出为object  防止所有行星全开时 类型改变
        }

        return [$details1, $details2];
    }

    /**
     * 获取太阳返照盘数据
     * @return array
     */
    protected function getSolarReturnData()
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $longitude = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $timestamp2 = $this->deal_time($this->advance);

        // 检测时间
//        if (!$this->checkTime($timestamp1, $timestamp2))
//        {
////            return false;
//        }

        $birth_JD = gregoriantojd(date('m', $timestamp1), date('d', $timestamp1), date('Y', $timestamp1)) + ((date('H', $timestamp1) + (date('i', $timestamp1) / 60)) / 24);
        $start_JD = gregoriantojd(date('m', $timestamp2), date('d', $timestamp2), date('Y', $timestamp2)) + ((date('H', $timestamp2) + (date('i', $timestamp2) / 60)) / 24);
        $days_alive = $start_JD - $birth_JD; // 总天数

        $year_ago = floor($days_alive / 365.2422);// 365.2422  365.2421990  365.25

        $now_before = strtotime("+$year_ago year", $timestamp1);
        $now_after = strtotime("+1 day", $now_before);

        $utdatenow = strftime("%d.%m.%Y", $timestamp1);
        $utnow = strftime("%H:%M:%S", $timestamp1);

        $utdatenow1 = strftime("%d.%m.%Y", $now_before);
        $utnow1 = strftime("%H:%M:%S", $now_before);

        $utdatenow2 = strftime("%d.%m.%Y", $now_after);
        $utnow2 = strftime("%H:%M:%S", $now_after);

        $options1 = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];
        $options2 = ['utdatenow' => $utdatenow1, 'utnow' => $utnow1, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];
        $options3 = ['utdatenow' => $utdatenow2, 'utnow' => $utnow2, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out1 = $this->execData($options1);
        $out2 = $this->execData($options2);
        $out3 = $this->execData($options3);

        // 出生生日那一天太阳位置
        $longtitude1 = number_format(explode(',', $out1[0])[0] * 1, 3);
        // 当年生日前一天的太阳位置
        $longtitude2 = number_format(explode(',', $out2[0])[0] * 1, 3);
        // 当年生日后一天太阳位置
        $longtitude3 = number_format(explode(',', $out3[0])[0] * 1, 3);

        $diff_longtitude = round(abs($longtitude3 - $longtitude2), 6);//度数差

        $diff_minutes = 24 * 60 * 60;//精确到秒

        $diff_influence = $diff_longtitude / $diff_minutes;// 每秒钟走的度数

        // 需要多少时间  回到需要的度数
        $second = floor(abs($longtitude1 - $longtitude2) / $diff_influence);// 总秒钟数

        if ($longtitude1 < $longtitude2) $now_before -= $second;

        else $now_before += $second;

        $now_before = $now_before - ($now_before % 60);// 只精确到分钟

        $utdatenow_test = strftime("%d.%m.%Y", $now_before);
        $utnow_test = strftime("%H:%M:%S", $now_before);

        $options = ['utdatenow' => $utdatenow_test, 'utnow' => $utnow_test, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out = $this->execData($options);

        $original_data = $this->getOriginalData($out);
        $this->array_remove($original_data);

        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1']);
        $phase = $this->planetPkPlanet($original_data, $original_data, true);
        foreach ($phase['planets'] as $k => $d)
        {
            $details['planets'][$k]['phase'] = $d['phase'];
            if (empty($d['phase'])) $details['planets'][$k]['phase'] = null;
        }

        if ($this->isAstrolabe === true)
        {
            $details['phase'] = $phase['phase'];

            $details['planets'] = (object)$details['planets'];// 指定输出为object  防止所有行星全开时 类型改变
        }

        $details['return_time'] = date("Y-m-d H:i", $now_before + $this->recode1['timezone'] * 3600);

        return $details;
    }

    /**
     * 获取太阳返照双盘数据
     * @return array
     */
    protected function getSolarReturnVsNatalData()
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $longitude = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $timestamp2 = $this->deal_time($this->advance);

        // 检测时间
//        if (!$this->checkTime($timestamp1, $timestamp2))
//        {
////            return false;
//        }

        $birth_JD = gregoriantojd(date('m', $timestamp1), date('d', $timestamp1), date('Y', $timestamp1)) + ((date('H', $timestamp1) + (date('i', $timestamp1) / 60)) / 24);
        $start_JD = gregoriantojd(date('m', $timestamp2), date('d', $timestamp2), date('Y', $timestamp2)) + ((date('H', $timestamp2) + (date('i', $timestamp2) / 60)) / 24);
        $days_alive = $start_JD - $birth_JD; // 总天数

        $year_ago = floor($days_alive / 365.2422);// 365.2422  365.2421990  365.25

        $now_before = strtotime("+$year_ago year", $timestamp1);
        $now_after = strtotime("+1 day", $now_before);

        $utdatenow = strftime("%d.%m.%Y", $timestamp1);
        $utnow = strftime("%H:%M:%S", $timestamp1);

        $utdatenow1 = strftime("%d.%m.%Y", $now_before);
        $utnow1 = strftime("%H:%M:%S", $now_before);

        $utdatenow2 = strftime("%d.%m.%Y", $now_after);
        $utnow2 = strftime("%H:%M:%S", $now_after);

        $options1 = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];
        $options2 = ['utdatenow' => $utdatenow1, 'utnow' => $utnow1, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];
        $options3 = ['utdatenow' => $utdatenow2, 'utnow' => $utnow2, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out1 = $this->execData($options1);
        $out2 = $this->execData($options2);
        $out3 = $this->execData($options3);

        // 出生生日那一天太阳位置
        $longtitude1 = number_format(explode(',', $out1[0])[0] * 1, 3);
        // 当年生日前一天的太阳位置
        $longtitude2 = number_format(explode(',', $out2[0])[0] * 1, 3);
        // 当年生日后一天太阳位置
        $longtitude3 = number_format(explode(',', $out3[0])[0] * 1, 3);

        $diff_longtitude = round(abs($longtitude3 - $longtitude2), 6);//度数差

        $diff_minutes = 24 * 60 * 60;//精确到秒

        $diff_influence = $diff_longtitude / $diff_minutes;// 每秒钟走的度数

        // 需要多少时间  回到需要的度数
        $second = floor(abs($longtitude1 - $longtitude2) / $diff_influence);// 总秒钟数

        if ($longtitude1 < $longtitude2) $now_before -= $second;

        else $now_before += $second;

        $now_before = $now_before - ($now_before % 60);// 只精确到分钟

        $utdatenow_test = strftime("%d.%m.%Y", $now_before);
        $utnow_test = strftime("%H:%M:%S", $now_before);

        $options = ['utdatenow' => $utdatenow_test, 'utnow' => $utnow_test, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out = $this->execData($options);

        $original_data1 = $this->getOriginalData($out1);
        $original_data2 = $this->getOriginalData($out);
        $this->array_remove($original_data1);
        $this->array_remove($original_data2);
        $details1 = $this->getPlanetHouseDetail($original_data1, $original_data1['hc1']);
        $details2 = $this->getPlanetHouseDetail($original_data2, $original_data1['hc1']);
        $phase1 = $this->planetPkPlanet($original_data1, $original_data2);
        $phase2 = $this->planetPkPlanet($original_data2, $original_data1);
        foreach ($phase1['planets'] as $k1 => $d1)
        {
            $details1['planets'][$k1]['phase'] = $d1['phase'];
            if (empty($d1['phase'])) $details1['planets'][$k1]['phase'] = null;
        }
        foreach ($phase2['planets'] as $k2 => $d2)
        {
            $details2['planets'][$k2]['phase'] = $d2['phase'];
            if (empty($d2['phase'])) $details2['planets'][$k2]['phase'] = null;
        }

        if ($this->isAstrolabe === true)
        {
            $details1['phase'] = $phase1['phase'];
            $details2['phase'] = $phase2['phase'];
            $details1['planets'] = (object)$details1['planets'];// 指定输出为object  防止所有行星全开时 类型改变
            $details2['planets'] = (object)$details2['planets'];// 指定输出为object  防止所有行星全开时 类型改变
        }


        $details1['return_time'] = $details2['return_time'] = date("Y-m-d H:i", $now_before + $this->recode1['timezone'] * 3600);

        return [$details1, $details2];
    }

    /**
     * 获取月亮返照盘数据
     * @return array
     */
    protected function getLunarReturnData()
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $longitude = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $timestamp2 = $this->deal_time($this->advance);

        // 检测时间
//        if (!$this->checkTime($timestamp1, $timestamp2))
//        {
////            return false;
//        }

        $birth_JD = gregoriantojd(date('m', $timestamp1), date('d', $timestamp1), date('Y', $timestamp1)) + ((date('H', $timestamp1) + (date('i', $timestamp1) / 60)) / 24);
        $start_JD = gregoriantojd(date('m', $timestamp2), date('d', $timestamp2), date('Y', $timestamp2)) + ((date('H', $timestamp2) + (date('i', $timestamp2) / 60)) / 24);
        $days_alive = $start_JD - $birth_JD; // 总天数

        $month_ago = floor($days_alive / 27.321661);// 总月数
        $day_ago = floor($month_ago * 27.321661);
        $now_before = strtotime("+$day_ago day", $timestamp1);
        $now_after = strtotime("+1 day", $now_before);

        $utdatenow = strftime("%d.%m.%Y", $timestamp1);
        $utnow = strftime("%H:%M:%S", $timestamp1);

        $utdatenow1 = strftime("%d.%m.%Y", $now_before);
        $utnow1 = strftime("%H:%M:%S", $now_before);

        $utdatenow2 = strftime("%d.%m.%Y", $now_after);
        $utnow2 = strftime("%H:%M:%S", $now_after);

        $options1 = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];
        $options2 = ['utdatenow' => $utdatenow1, 'utnow' => $utnow1, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];
        $options3 = ['utdatenow' => $utdatenow2, 'utnow' => $utnow2, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out1 = $this->execData($options1);
        $out2 = $this->execData($options2);
        $out3 = $this->execData($options3);

        // 出生生日那一天月亮位置
        $longtitude1 = number_format(explode(',', $out1[1])[0] * 1, 3);
        // 当年生日前一天的月亮位置
        $longtitude2 = number_format(explode(',', $out2[1])[0] * 1, 3);
        // 当年生日后一天月亮位置
        $longtitude3 = number_format(explode(',', $out3[1])[0] * 1, 3);

        $diff_longtitude = round(abs($longtitude3 - $longtitude2), 6);//度数差

        $diff_minutes = 24 * 60 * 60;//精确到秒

        $diff_influence = $diff_longtitude / $diff_minutes;// 每秒钟走的度数

        // 需要多少时间  回到需要的度数
        $second = round(abs($longtitude1 - $longtitude2) / $diff_influence);// 总秒钟数

        if ($longtitude1 < $longtitude2) $now_before -= $second;

        else $now_before += $second;

        $now_before = $now_before - ($now_before % 60);// 只精确到分钟

        $utdatenow_test = strftime("%d.%m.%Y", $now_before);
        $utnow_test = strftime("%H:%M:%S", $now_before);

        $options = ['utdatenow' => $utdatenow_test, 'utnow' => $utnow_test, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out = $this->execData($options);

        $original_data = $this->getOriginalData($out);
        $this->array_remove($original_data);

        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1']);
        $phase = $this->planetPkPlanet($original_data, $original_data, true);
        foreach ($phase['planets'] as $k => $d)
        {
            $details['planets'][$k]['phase'] = $d['phase'];
            if (empty($d['phase'])) $details['planets'][$k]['phase'] = null;
        }

        if ($this->isAstrolabe === true)
        {
            $details['phase'] = $phase['phase'];

            $details['planets'] = (object)$details['planets'];// 指定输出为object  防止所有行星全开时 类型改变
        }

        $details['return_time'] = date("Y-m-d H:i", $now_before + $this->recode1['timezone'] * 3600);

        return $details;
    }

    /**
     * 获取月亮返照双盘数据
     */
    protected function getLunarReturnVsNatalData()
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $longitude = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $timestamp2 = $this->deal_time($this->advance);

        // 检测时间
//        if (!$this->checkTime($timestamp1, $timestamp2))
//        {
////            return false;
//        }

        $birth_JD = gregoriantojd(date('m', $timestamp1), date('d', $timestamp1), date('Y', $timestamp1)) + ((date('H', $timestamp1) + (date('i', $timestamp1) / 60)) / 24);
        $start_JD = gregoriantojd(date('m', $timestamp2), date('d', $timestamp2), date('Y', $timestamp2)) + ((date('H', $timestamp2) + (date('i', $timestamp2) / 60)) / 24);
        $days_alive = $start_JD - $birth_JD; // 总天数

        $month_ago = floor($days_alive / 27.321661);// 总月数
        $day_ago = floor($month_ago * 27.321661);
        $now_before = strtotime("+$day_ago day", $timestamp1);
        $now_after = strtotime("+1 day", $now_before);

        $utdatenow = strftime("%d.%m.%Y", $timestamp1);
        $utnow = strftime("%H:%M:%S", $timestamp1);

        $utdatenow1 = strftime("%d.%m.%Y", $now_before);
        $utnow1 = strftime("%H:%M:%S", $now_before);

        $utdatenow2 = strftime("%d.%m.%Y", $now_after);
        $utnow2 = strftime("%H:%M:%S", $now_after);

        $options1 = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];
        $options2 = ['utdatenow' => $utdatenow1, 'utnow' => $utnow1, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];
        $options3 = ['utdatenow' => $utdatenow2, 'utnow' => $utnow2, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out1 = $this->execData($options1);
        $out2 = $this->execData($options2);
        $out3 = $this->execData($options3);

        // 出生生日那一天月亮位置
        $longtitude1 = number_format(explode(',', $out1[1])[0] * 1, 3);
        // 当年生日前一天的月亮位置
        $longtitude2 = number_format(explode(',', $out2[1])[0] * 1, 3);
        // 当年生日后一天月亮位置
        $longtitude3 = number_format(explode(',', $out3[1])[0] * 1, 3);

        $diff_longtitude = round(abs($longtitude3 - $longtitude2), 6);//度数差

        $diff_minutes = 24 * 60 * 60;//精确到秒

        $diff_influence = $diff_longtitude / $diff_minutes;// 每秒钟走的度数

        // 需要多少时间  回到需要的度数
        $second = round(abs($longtitude1 - $longtitude2) / $diff_influence);// 总秒钟数

        if ($longtitude1 < $longtitude2) $now_before -= $second;

        else $now_before += $second;

        $now_before = $now_before - ($now_before % 60);// 只精确到分钟

        $utdatenow_test = strftime("%d.%m.%Y", $now_before);
        $utnow_test = strftime("%H:%M:%S", $now_before);

        $options = ['utdatenow' => $utdatenow_test, 'utnow' => $utnow_test, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out = $this->execData($options);

        $original_data1 = $this->getOriginalData($out1);
        $original_data2 = $this->getOriginalData($out);
        $this->array_remove($original_data1);
        $this->array_remove($original_data2);
        $details1 = $this->getPlanetHouseDetail($original_data1, $original_data1['hc1']);
        $details2 = $this->getPlanetHouseDetail($original_data2, $original_data1['hc1']);
        $phase1 = $this->planetPkPlanet($original_data1, $original_data2);
        $phase2 = $this->planetPkPlanet($original_data2, $original_data1);
        foreach ($phase1['planets'] as $k1 => $d1)
        {
            $details1['planets'][$k1]['phase'] = $d1['phase'];
            if (empty($d1['phase'])) $details1['planets'][$k1]['phase'] = null;
        }
        foreach ($phase2['planets'] as $k2 => $d2)
        {
            $details2['planets'][$k2]['phase'] = $d2['phase'];
            if (empty($d2['phase'])) $details2['planets'][$k2]['phase'] = null;
        }

        if ($this->isAstrolabe === true)
        {
            $details1['phase'] = $phase1['phase'];
            $details2['phase'] = $phase2['phase'];
            $details1['planets'] = (object)$details1['planets'];// 指定输出为object  防止所有行星全开时 类型改变
            $details2['planets'] = (object)$details2['planets'];// 指定输出为object  防止所有行星全开时 类型改变
        }

        $details1['return_time'] = $details2['return_time'] = date("Y-m-d H:i", $now_before + $this->recode1['timezone'] * 3600);

        return [$details1, $details2];
    }

    /**
     * 获取法达盘数据
     */
    protected function getFirdariaData()
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $longitude = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $timestamp2 = $this->deal_time($this->advance);

        // 检测时间
//        if (!$this->checkTime($timestamp1, $timestamp2))
//        {
////            return false;
//        }

        $utdatenow = strftime("%d.%m.%Y", $timestamp1);
        $utnow = strftime("%H:%M:%S", $timestamp1);

        $birth_JD = gregoriantojd(date('m', $timestamp1), date('d', $timestamp1), date('Y', $timestamp1)) + ((date('H', $timestamp1) + (date('i', $timestamp1) / 60)) / 24);
        $start_JD = gregoriantojd(date('m', $timestamp2), date('d', $timestamp2), date('Y', $timestamp2)) + ((date('H', $timestamp2) + (date('i', $timestamp2) / 60)) / 24);
        $days_alive = $start_JD - $birth_JD; // 总天数
//        $days_alive = ($timestamp2 - $timestamp1) / 3600 / 24; // 总天数
        $years_alive = $days_alive / 365.2422;// 365.2422  365.2421990  365.25


        $options = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out = $this->execData($options);

        $original_data = $this->getOriginalData($out);
        $this->array_remove($original_data);
        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1']);
        $phase = $this->planetPkPlanet($original_data, $original_data, true);
        foreach ($phase['planets'] as $k => $d)
        {
            $details['planets'][$k]['phase'] = $d['phase'];
            if (empty($d['phase'])) $details['planets'][$k]['phase'] = null;
        }
        // 大运、小运
        $main_sub_luck = $this->getTheMainSubLuck($timestamp1, $years_alive);
        $details['firdaria'] = $main_sub_luck;

        if ($this->isAstrolabe === true)
        {
            $details['phase'] = $phase['phase'];

            $details['planets'] = (object)$details['planets'];// 指定输出为object  防止所有行星全开时 类型改变
        }

        return $details;
    }

    /**
     * 获取小限盘数据
     * @return array|bool
     */
    protected function getProfectionData()
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $longitude = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $timestamp2 = $this->deal_time($this->advance);
        // 检测时间
//        if (!$this->checkTime($timestamp1, $timestamp2))
//        {
////            return false;
//        }

        $utdatenow = strftime("%d.%m.%Y", $timestamp1);
        $utnow = strftime("%H:%M:%S", $timestamp1);

        $birth_JD = gregoriantojd(date('m', $timestamp1), date('d', $timestamp1), date('Y', $timestamp1)) + ((date('H', $timestamp1) + (date('i', $timestamp1) / 60)) / 24);
        $start_JD = gregoriantojd(date('m', $timestamp2), date('d', $timestamp2), date('Y', $timestamp2)) + ((date('H', $timestamp2) + (date('i', $timestamp2) / 60)) / 24);
        $days_alive = $start_JD - $birth_JD; // 总天数
//        $days_alive = ($timestamp2 - $timestamp1)/3600/24; // 总天数
        $years_alive = $days_alive / 365.2422;// 365.2422  365.2421990  365.25
        $months_alive = $this->getTheMonthAgo($timestamp1, $timestamp2);

        $options = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out = $this->execData($options);

        $original_data = $this->getOriginalData($out);
        $this->array_remove($original_data);
        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1']);
        $phase = $this->planetPkPlanet($original_data, $original_data, true);
        foreach ($phase['planets'] as $k => $d)
        {
            $details['planets'][$k]['phase'] = $d['phase'];
            if (empty($d['phase'])) $details['planets'][$k]['phase'] = null;
        }

        $profection_year = ceil($years_alive) % 12;
        $profection_month = ($months_alive) % 12;
        $profection_year = $profection_year === 0 ? 12 : $profection_year;
        $profection_month = $profection_month === 0 ? 12 : $profection_month;

        $time_use_year = $time_use_month = $timestamp2 + $this->advance['timezone'] * 3600 + $this->advance['is_summer'] * 3600;

        $month_day = $this->recode1['month'] . '月' . $this->recode1['day'] . '日';

        $start_year = strtotime("-$profection_year year", $time_use_year);
        $start_month = strtotime($this->advance['year'] . '-' . $this->recode1['month'] . '-' . $this->recode1['day']);
        $start_month = strtotime("+1 month", $start_month);
        $years_use = floor($years_alive) - ($profection_year - 1);
        // 12宫
        for ($i = 1; $i < 13; $i++)
        {
            $end_year = strtotime("+1 year", $start_year);
            $end_month = strtotime("+1 month", $start_month);
            $details['profection']['details'][$i] = [
                'start_year' => date("y年", $start_year) . $month_day,
                'end_year' => date("y年", $end_year) . $month_day,
                'years_old_start' => $years_use,
                'years_old_end' => $years_use + 0.99,
                'start_month' => date("y年m月d日", $start_month),
                'end_month' => date("y年m月d日", $end_month),
            ];
            $start_year = $end_year;
            $start_month = $end_month;
            $years_use++;
        }

        $details['profection']['year_house'] = $profection_year;
        $details['profection']['month_house'] = $profection_month;

        if ($this->isAstrolabe === true)
        {
            $details['phase'] = $phase['phase'];
            $details['planets'] = (object)$details['planets'];// 指定输出为object  防止所有行星全开时 类型改变
        }

        return $details;
    }

    /**
     * 获取比较盘数据
     */
    protected function getSynastryData()
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $utdatenow1 = strftime("%d.%m.%Y", $timestamp1);
        $utnow1 = strftime("%H:%M:%S", $timestamp1);

        $longitude1 = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude1 = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $exec_str = $this->exec_prefix . " -b{$utdatenow1} -ut{$utnow1} -p0 -eswe -house{$longitude1},{$latitude1},{$this->options['h_sys']} -fj -g, -head";
        exec($exec_str, $out);

        $timestamp2 = $this->deal_time($this->recode2);
        $utdatenow2 = strftime("%d.%m.%Y", $timestamp2);
        $utnow2 = strftime("%H:%M:%S", $timestamp2);

        $exec_str1 = $this->exec_prefix . " -b{$utdatenow1} -ut{$utnow1} -p0123456789DAmHt -eswe -house{$longitude1},{$latitude1},{$this->options['h_sys']} -flds -g, -head";
        $exec_str2 = $this->exec_prefix . " -b{$utdatenow2} -ut{$utnow2} -p0123456789DAmHt -eswe -house{$longitude1},{$latitude1},{$this->options['h_sys']} -flds -g, -head";

        exec($exec_str1, $out1);
        exec($exec_str2, $out2);
        $original_data1 = $this->getOriginalData($out1);
        $original_data2 = $this->getOriginalData($out2);
        $this->array_remove($original_data1);
        $this->array_remove($original_data2);
        $details1 = $this->getPlanetHouseDetail($original_data1, $original_data1['hc1']);
        $details2 = $this->getPlanetHouseDetail($original_data2, $original_data1['hc1']);
        $phase1 = $this->planetPkPlanet($original_data1, $original_data2);
        $phase2 = $this->planetPkPlanet($original_data2, $original_data1);
        foreach ($phase1['planets'] as $k1 => $d1)
        {
            $details1['planets'][$k1]['phase'] = $d1['phase'];
            if (empty($d1['phase'])) $details1['planets'][$k1]['phase'] = NULL;
        }
        foreach ($phase2['planets'] as $k2 => $d2)
        {
            $details2['planets'][$k2]['phase'] = $d2['phase'];
            if (empty($d2['phase'])) $details2['planets'][$k2]['phase'] = NULL;
        }

        // 需要获取画盘所需数据
        if ($this->isAstrolabe === true)
        {
            $details1['phase'] = $phase1['phase'];
            $details2['phase'] = $phase2['phase'];
            // 指定输出为object  防止所有行星全开时 类型改变
            $details1['planets'] = (object)$details1['planets'];
            $details2['planets'] = (object)$details2['planets'];
        } else
        {
            $details1 = $this->get_structure($details1);
            $details2 = $this->get_structure($details2);
        }

        return [$details1, $details2];
    }

    /**
     * 获取组合中点盘数据
     */
    protected function getCompositeData()
    {
        $timestamp1 = $this->deal_time($this->recode1);

        $utdatenow1 = strftime("%d.%m.%Y", $timestamp1);
        $utnow1 = strftime("%H:%M:%S", $timestamp1);

        $longitude1 = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude1 = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $exec_str = $this->exec_prefix . " -b{$utdatenow1} -ut{$utnow1} -p0 -eswe -house{$longitude1},{$latitude1},{$this->options['h_sys']} -fj -g, -head";
        exec($exec_str, $out);

        $timestamp2 = $this->deal_time($this->recode2);
        $utdatenow2 = strftime("%d.%m.%Y", $timestamp2);
        $utnow2 = strftime("%H:%M:%S", $timestamp2);

        $exec_str1 = $this->exec_prefix . " -b{$utdatenow1} -ut{$utnow1} -p0123456789DAmHt -eswe -house{$longitude1},{$latitude1},{$this->options['h_sys']} -flds -g, -head";
        $exec_str2 = $this->exec_prefix . " -b{$utdatenow2} -ut{$utnow2} -p0123456789DAmHt -eswe -house{$longitude1},{$latitude1},{$this->options['h_sys']} -flds -g, -head";

        exec($exec_str1, $out1);
        exec($exec_str2, $out2);
        $original_data1 = $this->getOriginalData($out1);
        $original_data2 = $this->getOriginalData($out2);
        $this->array_remove($original_data1);
        $this->array_remove($original_data2);

        $original_data = $this->getTheCompoisteCenter($original_data1, $original_data2);

        $this->array_remove($original_data);
        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1']);
        $phase = $this->planetPkPlanet($original_data, $original_data, true);
        foreach ($phase['planets'] as $k => $d)
        {
            $details['planets'][$k]['phase'] = $d['phase'];
            if (empty($d['phase'])) $details['planets'][$k]['phase'] = null;
        }

        if ($this->isAstrolabe === true)
        {
            $details['phase'] = $phase['phase'];

            $details['planets'] = (object)$details['planets'];// 指定输出为object  防止所有行星全开时 类型改变
        }
        return $details;
    }

    /**
     * 获取组合三次限盘数据
     * @param float $coef
     * @return array
     */
    protected function getCompositeThirdprogressedData($coef = 27.321661)
    {
        $timestamp1 = $this->deal_time($this->recode1);
        $longitude1 = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude1 = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $timestamp2 = $this->deal_time($this->recode2);
        $longitude2 = $this->recode2['longitude'] ?? ($this->recode2['long_deg'] + $this->recode2['long_min'] / 60) * $this->recode2['ew'];
        $latitude2 = $this->recode2['latitude'] ?? ($this->recode2['lat_deg'] + $this->recode2['lat_min'] / 60) * $this->recode2['ns'];

        $timestamp3 = $this->deal_time($this->advance);

        $birth_JD1 = gregoriantojd(date('m', $timestamp1), date('d', $timestamp1), date('Y', $timestamp1)) + ((date('H', $timestamp1) + (date('i', $timestamp1) / 60)) / 24);
        $birth_JD2 = gregoriantojd(date('m', $timestamp2), date('d', $timestamp2), date('Y', $timestamp2)) + ((date('H', $timestamp2) + (date('i', $timestamp2) / 60)) / 24);
        $start_JD = gregoriantojd(date('m', $timestamp3), date('d', $timestamp3), date('Y', $timestamp3)) + ((date('H', $timestamp3) + (date('i', $timestamp3) / 60)) / 24);
        $days_alive1 = $start_JD - $birth_JD1; // 总天数
        $days_alive2 = $start_JD - $birth_JD2; // 总天数
        $prog_time_to_add1 = $days_alive1 / $coef; // 多少月27.321661     27.3215865
        $prog_time_to_add2 = $days_alive2 / $coef; // 多少月27.321661     27.3215865

        $time_before_JD1 = $birth_JD1 + floor($prog_time_to_add1);
        $time_before_JD2 = $birth_JD2 + floor($prog_time_to_add2);

        //变化比率 //就是$prog_time_to_add的去掉整数的小数
        $time_change_pro1 = $prog_time_to_add1 - floor($prog_time_to_add1);
        $time_change_pro2 = $prog_time_to_add2 - floor($prog_time_to_add2);

        $date_before1 = strtotime(jdtogregorian($time_before_JD1));
        $date_after1 = strtotime('+1 day', $date_before1);

        $date_before2 = strtotime(jdtogregorian($time_before_JD2));
        $date_after2 = strtotime('+1 day', $date_before2);

        $utdatenow1 = strftime("%d.%m.%Y", $date_before1);
        $utnow1 = strftime("%H:%M:%S", $timestamp1);

        $utdatenow2 = strftime("%d.%m.%Y", $date_after1);
        $utnow2 = strftime("%H:%M:%S", $timestamp1);

        $utdatenow3 = strftime("%d.%m.%Y", $date_before2);
        $utnow3 = strftime("%H:%M:%S", $timestamp2);

        $utdatenow4 = strftime("%d.%m.%Y", $date_after2);
        $utnow4 = strftime("%H:%M:%S", $timestamp2);

        $options1 = ['utdatenow' => $utdatenow1, 'utnow' => $utnow1, 'longitude' => $longitude1, 'latitude' => $latitude1, 'h_sys' => $this->options['h_sys']];
        $options2 = ['utdatenow' => $utdatenow2, 'utnow' => $utnow2, 'longitude' => $longitude1, 'latitude' => $latitude1, 'h_sys' => $this->options['h_sys']];
        $options3 = ['utdatenow' => $utdatenow3, 'utnow' => $utnow3, 'longitude' => $longitude2, 'latitude' => $latitude2, 'h_sys' => $this->options['h_sys']];
        $options4 = ['utdatenow' => $utdatenow4, 'utnow' => $utnow4, 'longitude' => $longitude2, 'latitude' => $latitude2, 'h_sys' => $this->options['h_sys']];

        $out1 = $this->execData($options1);
        $out2 = $this->execData($options2);
        $out3 = $this->execData($options3);
        $out4 = $this->execData($options4);

        $calOut1 = $this->getProgressionThirdprogressed($out1, $out2, $time_change_pro1);
        $calOut2 = $this->getProgressionThirdprogressed($out3, $out4, $time_change_pro2);


        $original_data1 = $this->getOriginalData($calOut1);
        $original_data2 = $this->getOriginalData($calOut2);

        $original_data = $this->getTheCompoisteCenter($original_data1, $original_data2);

        $this->array_remove($original_data);
        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1']);
        $phase = $this->planetPkPlanet($original_data, $original_data, true);
        foreach ($phase['planets'] as $k => $d)
        {
            $details['planets'][$k]['phase'] = $d['phase'];
            if (empty($d['phase'])) $details['planets'][$k]['phase'] = null;
        }

        if ($this->isAstrolabe === true)
        {
            $details['phase'] = $phase['phase'];

            $details['planets'] = (object)$details['planets'];// 指定输出为object  防止所有行星全开时 类型改变
        }

        return $details;
    }

    /**
     * 获取比较三次限盘数据
     * @param float $coef
     * @return array
     */
    protected function getSynastryThirdprogressedData($coef = 27.321661)
    {
        $timestamp1 = $this->deal_time($this->recode1);
        $longitude1 = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude1 = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $timestamp2 = $this->deal_time($this->recode2);
        $longitude2 = $this->recode2['longitude'] ?? ($this->recode2['long_deg'] + $this->recode2['long_min'] / 60) * $this->recode2['ew'];
        $latitude2 = $this->recode2['latitude'] ?? ($this->recode2['lat_deg'] + $this->recode2['lat_min'] / 60) * $this->recode2['ns'];

        $timestamp3 = $this->deal_time($this->advance);

        $birth_JD1 = gregoriantojd(date('m', $timestamp1), date('d', $timestamp1), date('Y', $timestamp1)) + ((date('H', $timestamp1) + (date('i', $timestamp1) / 60)) / 24);
        $birth_JD2 = gregoriantojd(date('m', $timestamp2), date('d', $timestamp2), date('Y', $timestamp2)) + ((date('H', $timestamp2) + (date('i', $timestamp2) / 60)) / 24);
        $start_JD = gregoriantojd(date('m', $timestamp3), date('d', $timestamp3), date('Y', $timestamp3)) + ((date('H', $timestamp3) + (date('i', $timestamp3) / 60)) / 24);
        $days_alive1 = $start_JD - $birth_JD1; // 总天数
        $days_alive2 = $start_JD - $birth_JD2; // 总天数
        $prog_time_to_add1 = $days_alive1 / $coef; // 多少月27.321661     27.3215865
        $prog_time_to_add2 = $days_alive2 / $coef; // 多少月27.321661     27.3215865

        $time_before_JD1 = $birth_JD1 + floor($prog_time_to_add1);
        $time_before_JD2 = $birth_JD2 + floor($prog_time_to_add2);

        //变化比率 //就是$prog_time_to_add的去掉整数的小数
        $time_change_pro1 = $prog_time_to_add1 - floor($prog_time_to_add1);
        $time_change_pro2 = $prog_time_to_add2 - floor($prog_time_to_add2);

        $date_before1 = strtotime(jdtogregorian($time_before_JD1));
        $date_after1 = strtotime('+1 day', $date_before1);

        $date_before2 = strtotime(jdtogregorian($time_before_JD2));
        $date_after2 = strtotime('+1 day', $date_before2);

        $utdatenow1 = strftime("%d.%m.%Y", $date_before1);
        $utnow1 = strftime("%H:%M:%S", $timestamp1);

        $utdatenow2 = strftime("%d.%m.%Y", $date_after1);
        $utnow2 = strftime("%H:%M:%S", $timestamp1);

        $utdatenow3 = strftime("%d.%m.%Y", $date_before2);
        $utnow3 = strftime("%H:%M:%S", $timestamp2);

        $utdatenow4 = strftime("%d.%m.%Y", $date_after2);
        $utnow4 = strftime("%H:%M:%S", $timestamp2);

        $options1 = ['utdatenow' => $utdatenow1, 'utnow' => $utnow1, 'longitude' => $longitude1, 'latitude' => $latitude1, 'h_sys' => $this->options['h_sys']];
        $options2 = ['utdatenow' => $utdatenow2, 'utnow' => $utnow2, 'longitude' => $longitude1, 'latitude' => $latitude1, 'h_sys' => $this->options['h_sys']];
        $options3 = ['utdatenow' => $utdatenow3, 'utnow' => $utnow3, 'longitude' => $longitude2, 'latitude' => $latitude2, 'h_sys' => $this->options['h_sys']];
        $options4 = ['utdatenow' => $utdatenow4, 'utnow' => $utnow4, 'longitude' => $longitude2, 'latitude' => $latitude2, 'h_sys' => $this->options['h_sys']];

        $out1 = $this->execData($options1);
        $out2 = $this->execData($options2);
        $out3 = $this->execData($options3);
        $out4 = $this->execData($options4);

        $calOut1 = $this->getProgressionThirdprogressed($out1, $out2, $time_change_pro1);
        $calOut2 = $this->getProgressionThirdprogressed($out3, $out4, $time_change_pro2);


        $original_data1 = $this->getOriginalData($calOut1);
        $original_data2 = $this->getOriginalData($calOut2);

        $this->array_remove($original_data1);
        $this->array_remove($original_data2);
        $details1 = $this->getPlanetHouseDetail($original_data1, $original_data1['hc1']);
        $details2 = $this->getPlanetHouseDetail($original_data2, $original_data1['hc1']);
        $phase1 = $this->planetPkPlanet($original_data1, $original_data2);
        $phase2 = $this->planetPkPlanet($original_data2, $original_data1);
        foreach ($phase1['planets'] as $k1 => $d1)
        {
            $details1['planets'][$k1]['phase'] = $d1['phase'];
            if (empty($d1['phase'])) $details1['planets'][$k1]['phase'] = NULL;
        }
        foreach ($phase2['planets'] as $k2 => $d2)
        {
            $details2['planets'][$k2]['phase'] = $d2['phase'];
            if (empty($d2['phase'])) $details2['planets'][$k2]['phase'] = NULL;
        }

        // 需要获取画盘所需数据
        if ($this->isAstrolabe === true)
        {
            $details1['phase'] = $phase1['phase'];
            $details2['phase'] = $phase2['phase'];
            // 指定输出为object  防止所有行星全开时 类型改变
            $details1['planets'] = (object)$details1['planets'];
            $details2['planets'] = (object)$details2['planets'];
        } else
        {
            $details1 = $this->get_structure($details1);
            $details2 = $this->get_structure($details2);
        }

        return [$details1, $details2];
    }

    /**
     * 获取时空中点盘数据
     * @return array
     */
    protected function getDavisonData()
    {
        $timestamp1 = $this->deal_time($this->recode1);
        $longitude1 = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude1 = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $timestamp2 = $this->deal_time($this->recode2);
        $longitude2 = $this->recode2['longitude'] ?? ($this->recode2['long_deg'] + $this->recode2['long_min'] / 60) * $this->recode2['ew'];
        $latitude2 = $this->recode2['latitude'] ?? ($this->recode2['lat_deg'] + $this->recode2['lat_min'] / 60) * $this->recode2['ns'];

        $timestamp = ($timestamp1 + $timestamp2) / 2;
        $utdatenow = strftime("%d.%m.%Y", $timestamp);
        $utnow = strftime("%H:%M:%S", $timestamp);
        $longitude = ($longitude1 + $longitude2) / 2;
        $latitude = ($latitude1 + $latitude2) / 2;

        $options = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out = $this->execData($options);

        $original_data = $this->getOriginalData($out);
        $this->array_remove($original_data);
        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1']);
        $phase = $this->planetPkPlanet($original_data, $original_data, true);
        foreach ($phase['planets'] as $k => $d)
        {
            $details['planets'][$k]['phase'] = $d['phase'];
            if (empty($d['phase'])) $details['planets'][$k]['phase'] = null;
        }

        if ($this->isAstrolabe === true)
        {
            $details['phase'] = $phase['phase'];

            $details['planets'] = (object)$details['planets'];// 指定输出为object  防止所有行星全开时 类型改变
        }

        return $details;
    }

    /**
     * 获取时空三次限盘数据
     * @param float $coef
     * @return array
     */
    protected function getDavisonThirdprogressedData($coef = 27.321661)
    {
        $timestamp1 = $this->deal_time($this->recode1);
        $longitude1 = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude1 = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $timestamp2 = $this->deal_time($this->recode2);
        $longitude2 = $this->recode2['longitude'] ?? ($this->recode2['long_deg'] + $this->recode2['long_min'] / 60) * $this->recode2['ew'];
        $latitude2 = $this->recode2['latitude'] ?? ($this->recode2['lat_deg'] + $this->recode2['lat_min'] / 60) * $this->recode2['ns'];

        $timestamp = ($timestamp1 + $timestamp2) / 2;
        $utdatenow = strftime("%d.%m.%Y", $timestamp);
        $utnow = strftime("%H:%M:%S", $timestamp);
        $longitude = ($longitude1 + $longitude2) / 2;
        $latitude = ($latitude1 + $latitude2) / 2;

        $exec_str = $this->exec_prefix . " -b{$utdatenow} -ut{$utnow} -p0 -eswe -house{$longitude},{$latitude},{$this->options['h_sys']} -fj -g, -head";
        exec($exec_str, $out);

        $timestamp2 = $this->deal_time($this->advance);

        $birth_JD = gregoriantojd(date('m', $timestamp1), date('d', $timestamp1), date('Y', $timestamp1)) + ((date('H', $timestamp1) + (date('i', $timestamp1) / 60)) / 24);
        $start_JD = gregoriantojd(date('m', $timestamp2), date('d', $timestamp2), date('Y', $timestamp2)) + ((date('H', $timestamp2) + (date('i', $timestamp2) / 60)) / 24);

        $days_alive = $start_JD - $birth_JD; // 总天数
        $prog_time_to_add = $days_alive / $coef; // 即本命后第几天

        $time_before_JD = $birth_JD + floor($prog_time_to_add);

        //变化比率 //就是$prog_time_to_add的去掉整数的小数
        $time_change_pro = $prog_time_to_add - floor($prog_time_to_add);

        $date_before = strtotime(jdtogregorian($time_before_JD));
        $date_after = strtotime('+1 day', $date_before);

        $utdatenow1 = strftime("%d.%m.%Y", $date_before);
        $utnow1 = strftime("%H:%M:%S", $timestamp1);

        $utdatenow2 = strftime("%d.%m.%Y", $date_after);
        $utnow2 = strftime("%H:%M:%S", $timestamp1);

        $options1 = ['utdatenow' => $utdatenow1, 'utnow' => $utnow1, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];
        $options2 = ['utdatenow' => $utdatenow2, 'utnow' => $utnow2, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out1 = $this->execData($options1);
        $out2 = $this->execData($options2);

        $calOut = $this->getProgressionThirdprogressed($out1, $out2, $time_change_pro);

        $original_data = $this->getOriginalData($calOut);
        $this->array_remove($original_data);

        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1']);
        $phase = $this->planetPkPlanet($original_data, $original_data, true);

        foreach ($phase['planets'] as $k => $d)
        {
            $details['planets'][$k]['phase'] = $d['phase'];
            if (empty($d['phase'])) $details['planets'][$k]['phase'] = null;
        }

        // 绘制星盘时，不需要结构参数
        if ($this->isAstrolabe === true)
        {
            $details['phase'] = $phase['phase'];
            $details['planets'] = (object)$details['planets'];
            $details['time1'] = date('Y-m-d H:i:s', $date_before);
        } else
        {
            $details = $this->get_structure($details, true);
        }

        return $details;
    }

    /**
     * 获取马克思盘数据
     * @return array
     */
    protected function getMarksData()
    {
        $timestamp1 = $this->deal_time($this->recode1);
        $longitude1 = $this->recode1['longitude'] ?? ($this->recode1['long_deg'] + $this->recode1['long_min'] / 60) * $this->recode1['ew'];
        $latitude1 = $this->recode1['latitude'] ?? ($this->recode1['lat_deg'] + $this->recode1['lat_min'] / 60) * $this->recode1['ns'];

        $timestamp2 = $this->deal_time($this->recode2);
        $longitude2 = $this->recode2['longitude'] ?? ($this->recode2['long_deg'] + $this->recode2['long_min'] / 60) * $this->recode2['ew'];
        $latitude2 = $this->recode2['latitude'] ?? ($this->recode2['lat_deg'] + $this->recode2['lat_min'] / 60) * $this->recode2['ns'];

        $timestamp = 0.75 * $timestamp1 + 0.25 * $timestamp2;
        $utdatenow = strftime("%d.%m.%Y", $timestamp);
        $utnow = strftime("%H:%M:%S", $timestamp);
        $longitude = 0.75 * $longitude1 + 0.25 * $longitude2;
        $latitude = 0.75 * $latitude1 + 0.25 * $latitude2;

        $options = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out = $this->execData($options);

        $original_data = $this->getOriginalData($out);
        $this->array_remove($original_data);
        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1']);
        $phase = $this->planetPkPlanet($original_data, $original_data, true);
        foreach ($phase['planets'] as $k => $d)
        {
            $details['planets'][$k]['phase'] = $d['phase'];
            if (empty($d['phase'])) $details['planets'][$k]['phase'] = null;
        }

        if ($this->isAstrolabe === true)
        {
            $details['phase'] = $phase['phase'];

            $details['planets'] = (object)$details['planets'];// 指定输出为object  防止所有行星全开时 类型改变
        }

        return $details;
    }

    /**
     * 获取卜卦盘数据
     */
    protected function getDivinationData()
    {
        $timestamp = $this->deal_time($this->advance);
        $utdatenow = strftime("%d.%m.%Y", $timestamp);
        $utnow = strftime("%H:%M:%S", $timestamp);

        $longitude = $this->advance['longitude'];
        $latitude = $this->advance['latitude'];

        $options = ['utdatenow' => $utdatenow, 'utnow' => $utnow, 'longitude' => $longitude, 'latitude' => $latitude, 'h_sys' => $this->options['h_sys']];

        $out = $this->execData($options);

        $original_data = $this->getOriginalData($out);

        $this->array_remove($original_data);

        $details = $this->getPlanetHouseDetail($original_data, $original_data['hc1'], $this->advance['year']);
        /**
         * 计算带月亮进程的相位信息
         */
        $phase = $this->divination_phase($original_data, $is_kongwang);
        $phase2 = $this->planetPkPlanet($original_data, $original_data, true);
        foreach ($phase as $k => $d)
        {
            $details['planets'][$k]['phase'] = empty($d) ? null : $d;
        }

        $details = $this->get_structure($details);

        $details['characteristic'] = $this->recept_or_mutual_recept($details['planets']);

        $details['fortune'] = $this->get_fort_score($details, $this->advance['year']);

        $details = $this->get_house_info($utdatenow, $utnow, $longitude, $latitude, $details);
        $details['phase'] = $phase2['phase'];
        $details['planets'][1]['is_kongwang'] = $is_kongwang;
        $localtime = strtotime($this->advance['year'] . '-' . $this->advance['month'] . '-' . $this->advance['day'] . ' ' . $this->advance['hour'] . ':' . $this->advance['minute'] . ':00');
        $details['main_hour_planet'] = $this->hour_main_planet($localtime, $longitude, $latitude);
        $details['time'] = $localtime;
        // 指定输出为object  防止类型改变
        $details['characteristic'] = (object)$details['characteristic'];
        // 指定输出为object  防止所有行星全开时 类型改变
        $details['planets'] = (object)$details['planets'];

        return $details;
    }

    /**
     * 卜卦相位 （月亮：月亮进程）
     * @param array $data 当前盘所有数据
     * @param bool $is_kongwang 月亮是否空亡
     * @return array
     */
    protected function divination_phase($data, &$is_kongwang)
    {
        $phase = [];
        $phase_proess = [[], [], []];
        // 相位计算
        for ($i = 0; $i <= 20; $i++)
        {
            if (!isset($data['p1'][$i])) continue;
            // 初始化
            $phase[$i] = null;

            for ($j = 0; $j <= 20; $j++)
            {
                if (!isset($data['p1'][$j]) || $i == $j || ($i >= 17 && $j >= 17)) continue;
                $p1 = $data['p1'][$i];
                $p2 = $data['p1'][$j];

                $da = abs($p1 - $p2);
                if ($da > 180) $da = 360 - $da;
                $p1_orb = isset($this->options['planets_orb'][$i]) ? $this->options['planets_orb'][$i] : 0;// 星体1容许度
                $p2_orb = isset($this->options['planets_orb'][$j]) ? $this->options['planets_orb'][$j] : 0;// 星体2容许度
                $p_orb = $p1_orb + $p2_orb;
                // 相位判断
                $q = -1;

                $orb = 0;
                foreach ($this->options['asps_display'] as $asp)
                {
                    $asp_orb = $this->options['asps_orb'][$asp] ?? 0;

                    if (($da <= ($asp + $asp_orb + $p_orb)) && ($da >= ($asp - $asp_orb - $p_orb)))
                    {
                        $q = $asp;
                        $orb = $asp_orb + $p_orb;
                    }
                }
                // 计算出入相位
                if ($i >= ASC || $j >= ASC)
                {
                    $in_or_out = -1;
                } else
                {
                    $phase_orb = floatval(number_format(abs($da - $q), 6));
                    $in_or_out_status = $this->phase_in_or_out($q, $p1, $p2, $data['speed'][$i], $data['speed'][$j], $phase_orb);
                    if ($in_or_out_status) $in_or_out = 1;// 入相
                    else $in_or_out = 0;// 出相
                }

                // 计算月亮进程
                if ($i == 1 && $j < ASC)
                {
                    $in_sign_id1 = ceil($p1 / 30);
                    $in_sign_id2 = ceil($p2 / 30);
                    $pre_sign = $in_sign_id1 - 1 < 1 ? 12 : $in_sign_id1 - 1;
                    $next_sign = $in_sign_id1 + 1 > 12 ? 1 : $in_sign_id1 + 1;
                    $pre_cross_sign = $pre_sign > 6 ? $pre_sign - 6 : $pre_sign + 6;
                    $next_cross_sign = $next_sign > 6 ? $next_sign - 6 : $next_sign + 6;
                    $except_sign = [$pre_sign, $next_sign, $pre_cross_sign, $next_cross_sign];

                    if (in_array($in_sign_id2, $except_sign)) continue;// 先排除无法成相的四个星座 相邻两个星座

                    $in_sign_deg1 = $p1 - ($in_sign_id1 - 1) * 30;
                    $in_sign_deg2 = $p2 - ($in_sign_id2 - 1) * 30;

                    if ($q > -1)
                    {
                        $temp = [
                            'id' => $j,
                            'phase_e' => $q,
                            'phase_or_orb' => $orb,
                            'phase_orb' => floatval(number_format(abs($da - $q), 6)),
                            'phase_change' => $in_or_out,
                            'phase_proess' => '过去'
                        ];
                        if ($in_sign_deg1 > $in_sign_deg2)
                        {
                            $phase_proess[0][$i . '-' . $j] = $temp;
                        } else
                        {
                            $temp['phase_proess'] = '进行';

                            $phase_proess[1][$i . '-' . $j] = $temp;
                        }
                    } elseif ($q == -1)
                    {
                        $temp = [
                            'id' => $j,
                            'phase_e' => abs($in_sign_id1 - $in_sign_id2) * 30,
                            'phase_or_orb' => $orb,
                            'phase_orb' => floatval(number_format(abs($in_sign_deg1 - $in_sign_deg2), 6)),
                            'phase_change' => $in_or_out,
                            'phase_proess' => '过去'
                        ];
                        if ($in_sign_deg1 > $in_sign_deg2)
                        {
                            $phase_proess[0][$i . '-' . $j] = $temp;
                        } else
                        {
                            $temp['phase_proess'] = '未来';

                            $phase_proess[2][$i . '-' . $j] = $temp;
                        }
                    }

                    $phase[1] = [];
                } // 非月亮相位正常显示
                elseif ($i != 1 && $q > -1)
                {
                    $phase[$i][$i . '-' . $j] = [
                        'id' => $j,
                        'phase_e' => $q,
                        'phase_or_orb' => $orb,
                        'phase_orb' => floatval(number_format(abs($da - $q), 6)),
                        'phase_change' => $in_or_out,
                    ];
                }
            }
        }
        /**
         * 对月亮所有进程进行排序
         */
        $phase_proess[0] = resort($phase_proess[0], 'phase_orb', 'DESC');
        $phase_proess[1] = resort($phase_proess[1], 'phase_orb', 'ASC');
        $phase_proess[2] = resort($phase_proess[2], 'phase_orb', 'ASC');
        /**
         * 没有进行相&&未来相 空亡！
         */
        if (empty($phase_proess[1]) && empty($phase_proess[2]))
        {
            $is_kongwang = true;
        } else
        {
            $is_kongwang = false;
        }
        /**
         * 月亮进程更新到月亮相位中
         */
        $phase[1] = array_merge($phase_proess[0], $phase_proess[1], $phase_proess[2]);

        return $phase;
    }

    /**
     * 计算某时某地的时主星
     * @param null $timestamp 未处理过的当地时间
     * @param null $longitude 经度
     * @param null $latitude 纬度
     * @return mixed
     */
    protected function hour_main_planet($timestamp = null, $longitude = null, $latitude = null)
    {
        $planet_sequence = [0, 3, 2, 1, 6, 5, 4];// 周日日出后开始算
        $used = [];
        $j = 0;
        for ($i = 1; $i <= 7 * 24; $i++)
        {
            if ($j == 7) $j = 0;
            $used[] = $planet_sequence[$j];
            $j++;
        }
        //  周日为0  周一为1 ... 周六为6
        $start_week = (int)date("w", $timestamp);

        $start = $start_week * 24;

        $sun_info_now = $this->dateSunInfo($timestamp, $latitude, $longitude);
        /**
         * 日落之前
         */
        if ($timestamp <= $sun_info_now['sunset'])
        {
            $n = 0;
            $diff = (($sun_info_now['sunset'] - $sun_info_now['sunrise']) / 12);
            for ($s = $sun_info_now['sunrise']; $s <= $sun_info_now['sunset'];)
            {
                $next = $s + $diff;
                if ($timestamp >= $s && $timestamp <= $next)
                {
                    break;
                }
                $n++;
                $s = $next;
            }

            return $used[$start + $n];
        } else
        {
            // 求出下一天的日出时间
            $sun_info_tomorrow = $this->dateSunInfo($timestamp + 24 * 3600, $latitude, $longitude);
            $n = 0;
            $diff = (($sun_info_tomorrow['sunrise'] - $sun_info_now['sunset']) / 12);
            for ($s = $sun_info_now['sunset']; $s <= $sun_info_tomorrow['sunrise'];)
            {
                $next = $s + $diff;
                if ($timestamp >= $s && $timestamp <= $next)
                {
                    break;
                }
                $n++;
                $s = $next;
            }

            return $used[$start + $n];
        }
    }

    /**
     * 获取某时某地 太阳东升西落信息
     * @param null $time
     * @param float $latitude 规定纬度。
     * @param float $longitude 规定经度
     * 如果成功则返回一个数组，如果失败则返回 FALSE。
     * @return array
     */
    protected function dateSunInfo($time = null, $latitude = 31.7667, $longitude = 35.2333)
    {
        $sun_info = date_sun_info($time, $latitude, $longitude);

        return [
            'sunrise' => $sun_info['sunrise'],
            'sunset' => $sun_info['sunset'],
            'transit' => $sun_info['transit'],
        ];
    }
}
